diff options
author | sreeram@chromium.org <sreeram@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-20 07:16:51 +0000 |
---|---|---|
committer | sreeram@chromium.org <sreeram@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-20 07:16:51 +0000 |
commit | e41982a7fd5dfdc59803abdde459b0065ad57f30 (patch) | |
tree | 46d3b0ba8a2400a342692a2547e6a67d778ad9a2 | |
parent | 9599e96765be3adda8573939d7143dce771e37a4 (diff) | |
download | chromium_src-e41982a7fd5dfdc59803abdde459b0065ad57f30.zip chromium_src-e41982a7fd5dfdc59803abdde459b0065ad57f30.tar.gz chromium_src-e41982a7fd5dfdc59803abdde459b0065ad57f30.tar.bz2 |
Use search::Mode in InstantModel.
Major changes:
+ Use search::Mode in InstantModel, instead of a custom enum.
+ Better logic in Update(), SearchModeChanged(), ActiveTabChanged() and Show()
in InstantController, allowing us to delete some unnecessary code.
+ Make InstantController be always present in BrowserInstantController, thus
getting rid of ResetInstant() and related code and notifications.
+ Remove |mode_| from InstantController, opting for a pair of booleans instead,
which will pave the way for suggestions-only Instant (in the near future).
+ Move prefs related code from InstantController to BrowserInstantController.
+ Correctly avoid deleting InstantLoader::preview_delegate_ prematurely.
+ Refactor OmniboxLostFocus(), with code mostly borrowed from @samarth's
excellent work in http://codereview.chromium.org/10909109/.
+ Make Hide() private to InstantController. Yay!
+ Call ActiveTabChanged() from Browser, instead of from an independent observer
(BrowserInstantController), to enforce ordering requirements.
+ Added DVLOGs for easier development. My choice of commandline:
--vmodule=*instant*=1,*searchbox*=1
+ Refresh loader only when the omnibox is unfocused and the preview is hidden.
+ Remove a cocoa unittest that didn't seem to be testing anything worthwhile.
+ In Views code, make the ownership of the preview WebView clearer. I've been
unable to make it crash by closing the browser with the preview showing, so
I guess it works. If I missed something, please let me know.
Minor changes include inconsequential refactoring or renaming, making things
more private than public, updating copyright header in every file that was
touched, removing unnecessary includes, etc.
BUG=159012,161367,161270
R=sky@chromium.org
TEST=See bugs.
Review URL: https://chromiumcodereview.appspot.com/11417056
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168754 0039d316-1c4b-4281-b951-d872f2087c98
47 files changed, 814 insertions, 1150 deletions
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc index 1f7078e..32e2147 100644 --- a/chrome/browser/autocomplete/search_provider.cc +++ b/chrome/browser/autocomplete/search_provider.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -29,7 +29,6 @@ #include "chrome/browser/history/history.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/in_memory_database.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" @@ -37,6 +36,7 @@ #include "chrome/browser/search_engines/template_url_prepopulate_data.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/browser/ui/search/search.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -700,7 +700,8 @@ bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) { extras->GetList("google:suggesttype", &types); // Only accept relevance suggestions if Instant is disabled. - if (!is_keyword && !InstantController::IsInstantEnabled(profile_)) { + if (!is_keyword && + !chrome::BrowserInstantController::IsInstantEnabled(profile_)) { // Discard this list if its size does not match that of the suggestions. if (extras->GetList("google:suggestrelevance", &relevances) && relevances->GetSize() != results->GetSize()) @@ -1258,5 +1259,5 @@ void SearchProvider::UpdateDone() { // pending, and we're not waiting on instant. done_ = (!timer_.IsRunning() && (suggest_results_pending_ == 0) && (instant_finalized_ || - !InstantController::IsInstantEnabled(profile_))); + !chrome::BrowserInstantController::IsInstantEnabled(profile_))); } diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc index d3dc4e3..a5a3515 100644 --- a/chrome/browser/autocomplete/search_provider_unittest.cc +++ b/chrome/browser/autocomplete/search_provider_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,11 +17,11 @@ #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -211,7 +211,8 @@ void SearchProviderTest::QueryForInputAndSetWYTMatch( QueryForInput(text, string16(), false); profile_.BlockUntilHistoryProcessesPendingRequests(); ASSERT_NO_FATAL_FAILURE(FinishDefaultSuggestQuery()); - EXPECT_NE(InstantController::IsInstantEnabled(&profile_), provider_->done()); + EXPECT_NE(chrome::BrowserInstantController::IsInstantEnabled(&profile_), + provider_->done()); if (!wyt_match) return; ASSERT_GE(provider_->matches().size(), 1u); diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 14f61ca..98cf413 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -65,7 +65,6 @@ #include "chrome/browser/importer/importer_host.h" #include "chrome/browser/importer/importer_list.h" #include "chrome/browser/infobars/infobar_tab_helper.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/notifications/balloon_collection.h" @@ -3181,7 +3180,7 @@ void TestingAutomationProvider::GetInstantInfo(Browser* browser, DictionaryValue* args, IPC::Message* reply_message) { DictionaryValue* info = new DictionaryValue; - if (browser->instant_controller()->instant()) { + if (browser->instant_controller()) { InstantController* instant = browser->instant_controller()->instant(); info->SetBoolean("enabled", true); info->SetBoolean("active", (instant->GetPreviewContents() != NULL)); diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc index ac1ede5..5c49524 100644 --- a/chrome/browser/instant/instant_browsertest.cc +++ b/chrome/browser/instant/instant_browsertest.cc @@ -1,13 +1,10 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/stringprintf.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/instant/instant_loader.h" -#include "chrome/browser/instant/instant_model.h" #include "chrome/browser/instant/instant_model_observer.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/search_engines/template_url_service.h" @@ -34,11 +31,10 @@ class InstantTestModelObserver : public InstantModelObserver { public: - InstantTestModelObserver( - const InstantModel* model, - const InstantModel::PreviewState desired_preview_state) + InstantTestModelObserver(const InstantModel* model, + chrome::search::Mode::Type desired_mode_type) : model_(model), - desired_preview_state_(desired_preview_state) { + desired_mode_type_(desired_mode_type) { model_->AddObserver(this); } @@ -50,15 +46,15 @@ class InstantTestModelObserver : public InstantModelObserver { run_loop_.Run(); } - // InstantModelObserver overrides: + // Overridden from InstantModelObserver: virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE { - if (model.preview_state() == desired_preview_state_) + if (model.mode().mode == desired_mode_type_) run_loop_.Quit(); } private: const InstantModel* const model_; - const InstantModel::PreviewState desired_preview_state_; + const chrome::search::Mode::Type desired_mode_type_; base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(InstantTestModelObserver); @@ -98,7 +94,7 @@ class InstantTest : public InProcessBrowserTest { void FocusOmnibox() { // If the omnibox already has focus, just notify Instant. if (omnibox()->model()->has_focus()) - instant()->OnAutocompleteGotFocus(); + instant()->OmniboxGotFocus(); else browser()->window()->GetLocationBar()->FocusLocation(false); } @@ -117,8 +113,8 @@ class InstantTest : public InProcessBrowserTest { } void SetOmniboxTextAndWaitForInstantToShow(const std::string& text) { - InstantTestModelObserver observer(instant()->model(), - InstantModel::QUERY_RESULTS); + InstantTestModelObserver observer( + instant()->model(), chrome::search::Mode::MODE_SEARCH_SUGGESTIONS); SetOmniboxText(text); observer.WaitUntilDesiredPreviewState(); } @@ -130,15 +126,15 @@ class InstantTest : public InProcessBrowserTest { bool GetBoolFromJS(content::RenderViewHost* rvh, const std::string& script, bool* result) WARN_UNUSED_RESULT { - return content::ExecuteJavaScriptAndExtractBool( - rvh, std::wstring(), WrapScript(script), result); + return content::ExecuteJavaScriptAndExtractBool(rvh, std::wstring(), + WrapScript(script), result); } bool GetIntFromJS(content::RenderViewHost* rvh, const std::string& script, int* result) WARN_UNUSED_RESULT { - return content::ExecuteJavaScriptAndExtractInt( - rvh, std::wstring(), WrapScript(script), result); + return content::ExecuteJavaScriptAndExtractInt(rvh, std::wstring(), + WrapScript(script), result); } bool GetStringFromJS(content::RenderViewHost* rvh, @@ -215,7 +211,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OmniboxFocusLoadsInstant) { // Check that the page supports Instant, but it isn't showing. EXPECT_TRUE(instant()->loader()->supports_instant()); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // Adding a new tab shouldn't delete or recreate the TabContents; otherwise, // what's the point of preloading? @@ -233,7 +229,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OmniboxFocusLoadsInstant) { // Doing a search should also use the same preloaded page. SetOmniboxTextAndWaitForInstantToShow("query"); - EXPECT_EQ(InstantModel::QUERY_RESULTS, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_search_suggestions()); EXPECT_EQ(preview_tab, instant()->GetPreviewContents()); } @@ -253,21 +249,21 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OnChangeEvent) { &active_tab_onvisibilitycalls)); EXPECT_EQ(0, active_tab_onvisibilitycalls); - // Typing "query" into the omnibox causes the first onchange event. + // Typing "query" into the omnibox causes two onchange events. SetOmniboxTextAndWaitForInstantToShow("query"); // The page suggested "query suggestion" is inline autocompleted into the - // omnibox, causing the second onchange event. + // omnibox, causing the third onchange event. EXPECT_EQ(ASCIIToUTF16("query suggestion"), omnibox()->GetText()); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); - EXPECT_EQ(2, onchangecalls_); + EXPECT_EQ(3, onchangecalls_); - // Change the query and confirm that another onchange is sent. Since the new - // query is not a prefix of the hardcoded "query suggestion", no inline - // autocompletion happens, and thus, no fourth onchange event. + // Change the query and confirm that two more onchange events are sent. Since + // the new query is not a prefix of the hardcoded "query suggestion", no + // inline autocompletion happens, and thus, no sixth onchange event. SetOmniboxText("search"); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); - EXPECT_EQ(3, onchangecalls_); + EXPECT_EQ(5, onchangecalls_); EXPECT_EQ(1, onvisibilitycalls_); active_tab_onvisibilitycalls = -1; @@ -306,7 +302,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OnSubmitEvent) { // After the commit, Instant should not be showing. EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // The old loader is deleted and a new one is created. EXPECT_TRUE(instant()->GetPreviewContents()); @@ -367,7 +363,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OnCancelEvent) { // After the commit, Instant should not be showing. EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // The old loader is deleted and a new one is created. EXPECT_TRUE(instant()->GetPreviewContents()); @@ -499,13 +495,13 @@ IN_PROC_BROWSER_TEST_F(InstantTest, SuggestionIsEmpty) { SetOmniboxTextAndWaitForInstantToShow("query"); EXPECT_EQ(ASCIIToUTF16("query"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); EXPECT_TRUE(ExecuteScript("suggestion = []")); SetOmniboxTextAndWaitForInstantToShow("query sugg"); EXPECT_EQ(ASCIIToUTF16("query sugg"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); EXPECT_TRUE(ExecuteScript("suggestion = [{}]")); SetOmniboxTextAndWaitForInstantToShow("query suggest"); @@ -522,15 +518,15 @@ IN_PROC_BROWSER_TEST_F(InstantTest, RejectsURLs) { // Instant doesn't try to process them. SetOmniboxText(chrome::kChromeUICrashURL); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); SetOmniboxText(chrome::kChromeUIHangURL); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); SetOmniboxText(chrome::kChromeUIKillURL); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // Make sure that the URLs were never sent to the preview page. EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); @@ -548,7 +544,10 @@ IN_PROC_BROWSER_TEST_F(InstantTest, IntranetPathLooksLikeSearch) { // that Instant doesn't act on it. ui_test_utils::NavigateToURL(browser(), GURL("http://baby/beluga")); EXPECT_EQ(ASCIIToUTF16("baby/beluga"), omnibox()->GetText()); - EXPECT_FALSE(instant()->GetPreviewContents()); + + EXPECT_TRUE(instant()->GetPreviewContents()); + EXPECT_FALSE(instant()->IsCurrent()); + EXPECT_TRUE(instant()->model()->mode().is_default()); } // Test that transitions between searches and non-searches work as expected. @@ -565,40 +564,40 @@ IN_PROC_BROWSER_TEST_F(InstantTest, TransitionsBetweenSearchAndURL) { // place to indicate that the search is "out of date". EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); - EXPECT_EQ(2, onchangecalls_); + EXPECT_TRUE(instant()->model()->mode().is_default()); + EXPECT_EQ(3, onchangecalls_); EXPECT_EQ("", value_); // Type a search. Instant should show. SetOmniboxTextAndWaitForInstantToShow("search"); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); EXPECT_TRUE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::QUERY_RESULTS, instant()->model()->preview_state()); - EXPECT_EQ(3, onchangecalls_); + EXPECT_TRUE(instant()->model()->mode().is_search_suggestions()); + EXPECT_EQ(5, onchangecalls_); EXPECT_EQ("search", value_); // Type another URL. The preview should be hidden. SetOmniboxText("http://terrible/terror"); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); - EXPECT_EQ(4, onchangecalls_); + EXPECT_TRUE(instant()->model()->mode().is_default()); + EXPECT_EQ(6, onchangecalls_); EXPECT_EQ("", value_); // Type the same search as before. SetOmniboxTextAndWaitForInstantToShow("search"); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); EXPECT_TRUE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::QUERY_RESULTS, instant()->model()->preview_state()); - EXPECT_EQ(5, onchangecalls_); + EXPECT_TRUE(instant()->model()->mode().is_search_suggestions()); + EXPECT_EQ(8, onchangecalls_); EXPECT_EQ("search", value_); // Revert the omnibox. - omnibox()->model()->OnEscapeKeyPressed(); + omnibox()->RevertAll(); EXPECT_TRUE(UpdateSearchState(instant()->GetPreviewContents())); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); - EXPECT_EQ(6, onchangecalls_); + EXPECT_TRUE(instant()->model()->mode().is_default()); + EXPECT_EQ(9, onchangecalls_); EXPECT_EQ("", value_); } @@ -610,7 +609,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DoesNotCommitURLsOne) { // Type a URL. The Instant preview shouldn't be showing. SetOmniboxText("http://deadly/nadder"); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // Unfocus and refocus the omnibox. ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER); @@ -623,7 +622,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DoesNotCommitURLsOne) { // The omnibox text hasn't changed, so Instant still shouldn't be showing. EXPECT_EQ(ASCIIToUTF16("http://deadly/nadder"), omnibox()->GetText()); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // Commit the URL. The omnibox should reflect the URL minus the scheme. browser()->window()->GetLocationBar()->AcceptInput(); @@ -635,7 +634,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DoesNotCommitURLsOne) { // Instant shouldn't have done anything. EXPECT_EQ(preview_tab, instant()->GetPreviewContents()); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); } // Test that Instant can't be fooled into committing a URL. @@ -652,11 +651,11 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DoesNotCommitURLsTwo) { // Type a URL. This causes the preview to be hidden. SetOmniboxText("http://hideous/zippleback"); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // Pretend the omnibox got focus. It already had focus, so we are just trying // to tickle a different code path. - instant()->OnAutocompleteGotFocus(); + instant()->OmniboxGotFocus(); // Commit the URL. As before, check that Instant wasn't committed. browser()->window()->GetLocationBar()->AcceptInput(); @@ -668,7 +667,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DoesNotCommitURLsTwo) { // As before, Instant shouldn't have done anything. EXPECT_EQ(preview_tab, instant()->GetPreviewContents()); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); } // Test that a non-Instant search provider shows no previews. @@ -845,10 +844,10 @@ IN_PROC_BROWSER_TEST_F(InstantTest, MAYBE_NewWindowDismissesInstant) { Browser* previous_window = browser(); EXPECT_TRUE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::QUERY_RESULTS, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_search_suggestions()); InstantTestModelObserver observer(instant()->model(), - InstantModel::NOT_READY); + chrome::search::Mode::MODE_DEFAULT); chrome::NewEmptyWindow(browser()->profile()); observer.WaitUntilDesiredPreviewState(); @@ -856,33 +855,37 @@ IN_PROC_BROWSER_TEST_F(InstantTest, MAYBE_NewWindowDismissesInstant) { // browser() accessor should still give us the first window's Browser object. EXPECT_EQ(previous_window, browser()); EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); } -// Test that: -// - Instant loader is recreated on OnStaleLoader call when it is hidden. -// - Instant loader is not recreated on OnStaleLoader call when it is visible. -// - Instant loader is recreated when omnibox loses focus after the timer stops. +// Test that the Instant loader is recreated when all these conditions are met: +// - The stale loader timer has fired. +// - The preview is not showing. +// - The omnibox doesn't have focus. IN_PROC_BROWSER_TEST_F(InstantTest, InstantLoaderRefresh) { ASSERT_NO_FATAL_FAILURE(SetupInstant()); FocusOmniboxAndWaitForInstantSupport(); - // Instant is not showing, so OnstaleLoader() should recreate the preview. - EXPECT_TRUE(instant()->loader()->supports_instant()); + // The preview is refreshed only after all three conditions above are met. + SetOmniboxTextAndWaitForInstantToShow("query"); + instant()->stale_loader_timer_.Stop(); instant()->OnStaleLoader(); + EXPECT_TRUE(instant()->loader()->supports_instant()); + instant()->Hide(true); + EXPECT_TRUE(instant()->loader()->supports_instant()); + instant()->OmniboxLostFocus(NULL); EXPECT_FALSE(instant()->loader()->supports_instant()); - // Show Instant. + // Try with a different ordering. SetOmniboxTextAndWaitForInstantToShow("query"); - - // Instant is showing, so OnStaleLoader() shouldn't kill the preview. instant()->stale_loader_timer_.Stop(); instant()->OnStaleLoader(); - EXPECT_EQ(InstantModel::QUERY_RESULTS, instant()->model()->preview_state()); - - // The preview should be recreated once the omnibox loses focus. EXPECT_TRUE(instant()->loader()->supports_instant()); - instant()->OnAutocompleteLostFocus(NULL); + instant()->OmniboxLostFocus(NULL); + // TODO(sreeram): Currently, OmniboxLostFocus() calls Hide(). Eventually, + // when it stops hiding the preview, uncomment these two lines below: + // EXPECT_TRUE(instant()->loader()->supports_instant()); + // instant()->Hide(true); EXPECT_FALSE(instant()->loader()->supports_instant()); } @@ -896,38 +899,38 @@ IN_PROC_BROWSER_TEST_F(InstantTest, SuggestionsAreCaseInsensitive) { SetOmniboxTextAndWaitForInstantToShow("in"); EXPECT_EQ(ASCIIToUTF16("instant"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow("IN"); EXPECT_EQ(ASCIIToUTF16("INSTANT"), omnibox()->GetText()); // U+0130 == LATIN CAPITAL LETTER I WITH DOT ABOVE EXPECT_TRUE(ExecuteScript("suggestion = [ { value: '\\u0130NSTANT' } ]")); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow("i"); EXPECT_EQ(WideToUTF16(L"i\u0307nstant"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow("I"); EXPECT_EQ(WideToUTF16(L"I\u0307nstant"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow(WideToUTF8(L"i\u0307")); EXPECT_EQ(WideToUTF16(L"i\u0307nstant"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow(WideToUTF8(L"I\u0307")); EXPECT_EQ(WideToUTF16(L"I\u0307nstant"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow(WideToUTF8(L"\u0130")); EXPECT_EQ(WideToUTF16(L"\u0130NSTANT"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow("in"); EXPECT_EQ(ASCIIToUTF16("in"), omnibox()->GetText()); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow("IN"); EXPECT_EQ(ASCIIToUTF16("IN"), omnibox()->GetText()); @@ -937,7 +940,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, SuggestionsAreCaseInsensitive) { // U+1E0B = LATIN SMALL LETTER D WITH DOT ABOVE EXPECT_TRUE(ExecuteScript("suggestion = [ { value: '\\u1e0d\\u0307oh' } ]")); - instant()->Hide(); + omnibox()->RevertAll(); SetOmniboxTextAndWaitForInstantToShow(WideToUTF8(L"\u1e0b\u0323")); EXPECT_EQ(WideToUTF16(L"\u1e0b\u0323oh"), omnibox()->GetText()); } @@ -985,7 +988,7 @@ IN_PROC_BROWSER_TEST_F(InstantTest, CommitInNewTab) { // After the commit, Instant should not be showing. EXPECT_FALSE(instant()->IsCurrent()); - EXPECT_EQ(InstantModel::NOT_READY, instant()->model()->preview_state()); + EXPECT_TRUE(instant()->model()->mode().is_default()); // The old loader is deleted and a new one is created. EXPECT_TRUE(instant()->GetPreviewContents()); diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc index 4f8ba01..09aee03 100644 --- a/chrome/browser/instant/instant_controller.cc +++ b/chrome/browser/instant/instant_controller.cc @@ -1,14 +1,12 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/instant/instant_controller.h" #include "base/command_line.h" -#include "base/i18n/case_conversion.h" #include "base/metrics/histogram.h" #include "base/string_util.h" -#include "base/time.h" #include "base/utf_string_conversions.h" #include "chrome/browser/autocomplete/autocomplete_provider.h" #include "chrome/browser/google/google_util.h" @@ -17,24 +15,18 @@ #include "chrome/browser/history/history_tab_helper.h" #include "chrome/browser/instant/instant_loader.h" #include "chrome/browser/platform_util.h" -#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser_instant_controller.h" -#include "chrome/browser/ui/search/search.h" #include "chrome/browser/ui/search/search_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" #include "net/base/escape.h" #include "unicode/normalizer2.h" -#include "unicode/unistr.h" #if defined(TOOLKIT_VIEWS) #include "ui/views/widget/widget.h" @@ -55,22 +47,12 @@ const int kMaxInstantSupportFailures = 10; // reloaded so that the page does not become stale. const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000; -std::string ModeToString(InstantController::Mode mode) { - switch (mode) { - case InstantController::EXTENDED: return "_Extended"; - case InstantController::INSTANT: return "_Instant"; - case InstantController::DISABLED: return "_Disabled"; - } - - NOTREACHED(); - return std::string(); -} - -void AddSessionStorageHistogram(InstantController::Mode mode, +void AddSessionStorageHistogram(bool extended_enabled, const TabContents* tab1, const TabContents* tab2) { base::Histogram* histogram = base::BooleanHistogram::FactoryGet( - "Instant.SessionStorageNamespace" + ModeToString(mode), + std::string("Instant.SessionStorageNamespace") + + (extended_enabled ? "_Extended" : "_Instant"), base::Histogram::kUmaTargetedHistogramFlag); const content::SessionStorageNamespaceMap& session_storage_map1 = tab1->web_contents()->GetController().GetSessionStorageNamespaceMap(); @@ -83,8 +65,7 @@ void AddSessionStorageHistogram(InstantController::Mode mode, for (content::SessionStorageNamespaceMap::const_iterator it1 = session_storage_map1.begin(), it2 = session_storage_map2.begin(); - it1 != session_storage_map1.end() && - it2 != session_storage_map2.end(); + it1 != session_storage_map1.end() && it2 != session_storage_map2.end(); ++it1, ++it2) { if (it1->first != it2->first || it1->second != it2->second) { is_session_storage_the_same = false; @@ -95,17 +76,6 @@ void AddSessionStorageHistogram(InstantController::Mode mode, histogram->AddBoolean(is_session_storage_the_same); } -InstantController::Mode GetModeForProfile(Profile* profile) { - if (chrome::search::IsInstantExtendedAPIEnabled(profile)) - return InstantController::EXTENDED; - - if (!profile || profile->IsOffTheRecord() || !profile->GetPrefs() || - !profile->GetPrefs()->GetBoolean(prefs::kInstantEnabled)) - return InstantController::DISABLED; - - return InstantController::INSTANT; -} - string16 Normalize(const string16& str) { UErrorCode status = U_ZERO_ERROR; const icu::Normalizer2* normalizer = @@ -130,127 +100,187 @@ bool NormalizeAndStripPrefix(string16* text, const string16& prefix) { return false; } -InstantModel::PreviewState GetNewPreviewState(InstantShownReason reason) { - return reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT ? - InstantModel::CUSTOM_NTP_CONTENT : InstantModel::QUERY_RESULTS; +// For TOOLKIT_VIEWS, the top level widget is always focused. If the focus +// change originated in views determine the child Widget from the view that is +// being focused. +gfx::NativeView GetViewGainingFocus(gfx::NativeView view_gaining_focus) { +#if defined(TOOLKIT_VIEWS) + views::Widget* widget = view_gaining_focus ? + views::Widget::GetWidgetForNativeView(view_gaining_focus) : NULL; + if (widget) { + views::FocusManager* focus_manager = widget->GetFocusManager(); + if (focus_manager && focus_manager->is_changing_focus() && + focus_manager->GetFocusedView() && + focus_manager->GetFocusedView()->GetWidget()) { + return focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); + } + } +#endif + return view_gaining_focus; } -} // namespace +// Returns true if |view| is the top-level contents view or a child view in the +// view hierarchy of |contents|. +bool IsViewInContents(gfx::NativeView view, content::WebContents* contents) { + content::RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView(); + if (!view || !rwhv) + return false; -InstantController::~InstantController() { -} + gfx::NativeView tab_view = contents->GetNativeView(); + if (view == rwhv->GetNativeView() || view == tab_view) + return true; -// static -InstantController* InstantController::CreateInstant( - Profile* profile, - chrome::BrowserInstantController* browser) { - const Mode mode = GetModeForProfile(profile); - return mode == DISABLED ? NULL : new InstantController(browser, mode); -} + // Walk up the view hierarchy to determine if the view is a subview of the + // WebContents view (such as a windowed plugin or http auth dialog). + while (view) { + view = platform_util::GetParent(view); + if (view == tab_view) + return true; + } -// static -bool InstantController::IsExtendedAPIEnabled(Profile* profile) { - return GetModeForProfile(profile) == EXTENDED; + return false; } -// static -bool InstantController::IsInstantEnabled(Profile* profile) { - const Mode mode = GetModeForProfile(profile); - return mode == EXTENDED || mode == INSTANT; +} // namespace + +InstantController::InstantController(chrome::BrowserInstantController* browser, + bool extended_enabled) + : browser_(browser), + extended_enabled_(extended_enabled), + instant_enabled_(false), + model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + last_verbatim_(false), + last_transition_type_(content::PAGE_TRANSITION_LINK), + last_match_was_search_(false), + is_omnibox_focused_(false) { } -// static -void InstantController::RegisterUserPrefs(PrefService* prefs) { - prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, false, - PrefService::SYNCABLE_PREF); - prefs->RegisterBooleanPref(prefs::kInstantEnabled, false, - PrefService::SYNCABLE_PREF); +InstantController::~InstantController() { } bool InstantController::Update(const AutocompleteMatch& match, const string16& user_text, const string16& full_text, - bool verbatim) { - const TabContents* active_tab = browser_->GetActiveTabContents(); - - // We could get here with no active tab if the Browser is closing. - if (!active_tab) { - Hide(); + const bool verbatim, + const bool user_input_in_progress, + const bool omnibox_popup_is_open) { + if (!extended_enabled_ && !instant_enabled_) return false; - } - std::string instant_url; - Profile* profile = active_tab->profile(); + DVLOG(1) << "Update: " << AutocompleteMatch::TypeToString(match.type) + << " user_text='" << user_text << "' full_text='" << full_text << "'" + << " verbatim=" << verbatim << " typing=" << user_input_in_progress + << " popup=" << omnibox_popup_is_open; - // If the match's TemplateURL is valid, it's a search query; use it. If it's - // not valid, it's likely a URL; in EXTENDED mode, try using the default - // search engine's TemplateURL instead. - const GURL& tab_url = active_tab->web_contents()->GetURL(); - if (GetInstantURL(match.GetTemplateURL(profile, false), tab_url, - &instant_url)) { - ResetLoader(instant_url, active_tab); - } else if (mode_ != EXTENDED || !CreateDefaultLoader()) { - Hide(); + // If the popup is open, the user has to be typing. + DCHECK(!omnibox_popup_is_open || user_input_in_progress); + + // If the popup is closed, there should be no inline autocompletion. + DCHECK(omnibox_popup_is_open || user_text == full_text) << user_text << "|" + << full_text; + + // If there's inline autocompletion, the query has to be verbatim. + DCHECK(user_text == full_text || verbatim) << user_text << "|" << full_text; + + // If there's no text in the omnibox, the user can't have typed any. + DCHECK(!full_text.empty() || user_text.empty()) << user_text; + + // If the user isn't typing, and the popup is closed, there can't be any + // user-typed text. + DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) + << user_text; + + // In non-extended mode, SearchModeChanged() is never called, so fake it. The + // mode is set to "disallow suggestions" here, so that if one of the early + // "return false" conditions is hit, suggestions will be disallowed. If the + // query is sent to the loader, the mode is set to "allow" further below. + if (!extended_enabled_) + search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; + + // If there's no active tab, the browser is closing. + const TabContents* const active_tab = browser_->GetActiveTabContents(); + if (!active_tab) { + Hide(true); return false; } - if (full_text.empty()) { - // In extended mode, blank the preview instead of flashing the NTP when the - // user backspaces out the omnibox text. (Assume they still intend to edit, - // so showing the NTP would just be distracting.) - if (mode_ == EXTENDED) - SendBlankQuery(); - else - Hide(); + if (extended_enabled_) { + // If the user isn't typing, and the omnibox popup isn't open, the omnibox + // text is a regular URL (due to a navigation). No query here to see. + if (!user_input_in_progress && !omnibox_popup_is_open) { + // The preview may be showing NTP content that's still relevant, so let + // ModeChanged() and ActiveTabChanged() deal with hiding it if necessary. + return false; + } + } else if (!omnibox_popup_is_open || full_text.empty()) { + // In non-extended mode, Instant processes the query only if the user is + // actively typing (hence the popup is open) and they haven't just deleted + // all the text (|full_text| is not empty). + // + // It's possible that Update() was called if the user clicked the preview + // page while IME composition was active. In that case, we still want to + // commit on mouse up, so don't call Hide(). + if (!GetPreviewContents() || !loader_->IsPointerDownFromActivate()) + Hide(true); return false; } - // Track the non-Instant search URL for this query. - url_for_history_ = match.destination_url; - last_transition_type_ = match.transition; - last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type); - - // If the query text hasn't changed, don't send an update to the loader. Just - // reuse the last suggestion, as it's still valid. - if (user_text == last_user_text_ && verbatim == last_verbatim_) { - browser_->SetInstantSuggestion(last_suggestion_); - return last_match_was_search_; + // If the match's TemplateURL is valid, it's a search query; use it. If it's + // not valid, it's likely a URL; in extended mode, try using the default + // search engine's TemplateURL instead. + Profile* const profile = active_tab->profile(); + const bool match_is_search = AutocompleteMatch::IsSearchType(match.type); + + // Ensure we have a loader that can process this match. First, try to use the + // TemplateURL of the |match|. If that's invalid, in non-extended mode, stop. + // In extended mode, try using the default search engine, but only when the + // match is for a URL (i.e., not some other kind of non-Instant search). + // A completely blank query shows up as a search, and we do want to allow + // that, hence the "!full_text.empty()" clause. + if (!ResetLoader(match.GetTemplateURL(profile, false), active_tab) && + (!extended_enabled_ || (match_is_search && !full_text.empty()) || + !CreateDefaultLoader())) { + Hide(true); + return false; } - // The last suggestion and its associated parameters can be preserved if the - // user continues typing the same query as the suggested text is showing. - // Suggestions are only reused with INSTANT_COMPLETE_NEVER behavior. + // If the user continues typing the same query as the suggested text is + // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). bool reused_suggestion = false; if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER) { - if (StartsWith(user_text, last_user_text_, false)) { - // If the new user text is longer than the last user text, we need to - // normalize any added characters. - reused_suggestion = NormalizeAndStripPrefix(&last_suggestion_.text, - string16(user_text, last_user_text_.size())); - } else if (StartsWith(last_user_text_, user_text, false)) { - // If the new user text is a prefix of the last user text, no - // normalization is necessary. + if (StartsWith(last_user_text_, user_text, false) && !user_text.empty()) { + // The user is backspacing away characters. last_suggestion_.text.insert(0, last_user_text_, user_text.size(), last_user_text_.size() - user_text.size()); reused_suggestion = true; + } else if (StartsWith(user_text, last_user_text_, false)) { + // The user is typing forward. Normalize any added characters. + reused_suggestion = NormalizeAndStripPrefix(&last_suggestion_.text, + string16(user_text, last_user_text_.size())); } } last_user_text_ = user_text; last_full_text_ = full_text; last_verbatim_ = verbatim; + if (!reused_suggestion) last_suggestion_ = InstantSuggestion(); - if (model_.preview_state() == InstantModel::NOT_READY) { - model_.SetPreviewState(InstantModel::AWAITING_SUGGESTIONS, - 0, INSTANT_SIZE_PERCENT); - } + + last_transition_type_ = match.transition; + last_match_was_search_ = match_is_search; + url_for_history_ = match.destination_url; // Store the first interaction time for use with latency histograms. if (first_interaction_time_.is_null()) first_interaction_time_ = base::Time::Now(); - loader_->Update(mode_ == EXTENDED ? user_text : full_text, verbatim); + // Allow search suggestions. In extended mode, SearchModeChanged() will set + // this, but it's not called in non-extended mode, so fake it. + if (!extended_enabled_) + search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; + + loader_->Update(extended_enabled_ ? user_text : full_text, verbatim); content::NotificationService::current()->Notify( chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, @@ -264,7 +294,7 @@ bool InstantController::Update(const AutocompleteMatch& match, // Though we may have handled a URL match above, we return false here, so that // omnibox prerendering can kick in. TODO(sreeram): Remove this (and always // return true) once we are able to commit URLs as well. - return last_match_was_search_; + return match_is_search; } // TODO(tonyg): This method only fires when the omnibox bounds change. It also @@ -274,6 +304,10 @@ void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { return; omnibox_bounds_ = bounds; + + if (!extended_enabled_ && !instant_enabled_) + return; + if (omnibox_bounds_.height() > last_omnibox_bounds_.height()) { update_bounds_timer_.Stop(); SendBoundsToPage(); @@ -286,9 +320,10 @@ void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { void InstantController::HandleAutocompleteResults( const std::vector<AutocompleteProvider*>& providers) { - if (mode_ != EXTENDED || !GetPreviewContents()) + if (!extended_enabled_ || !GetPreviewContents()) return; + DVLOG(1) << "AutocompleteResults:"; std::vector<InstantAutocompleteResult> results; for (ACProviders::const_iterator provider = providers.begin(); provider != providers.end(); ++provider) { @@ -300,6 +335,9 @@ void InstantController::HandleAutocompleteResults( result.description = match->description; result.destination_url = UTF8ToUTF16(match->destination_url.spec()); result.relevance = match->relevance; + DVLOG(1) << " " << result.relevance << " " << result.type << " " + << result.provider << " " << result.destination_url << " '" + << result.description << "'"; results.push_back(result); } } @@ -308,73 +346,29 @@ void InstantController::HandleAutocompleteResults( } bool InstantController::OnUpOrDownKeyPressed(int count) { - if (mode_ != EXTENDED || !GetPreviewContents()) + if (!extended_enabled_ || !GetPreviewContents()) return false; loader_->OnUpOrDownKeyPressed(count); return true; } -void InstantController::OnEscapeKeyPressed() { - if (mode_ == EXTENDED && - active_tab_mode_.is_search_suggestions() && - active_tab_mode_.is_origin_ntp() && - loader_.get() && loader_->HasShownCustomNTPContent()) { - // We are showing search suggestions on top of an extended mode NTP where - // the page previously showed custom NTP content. The user pressed escape - // so will return to the NTP. To avoid janky flicker, assume the page will - // show custom NTP content again, and do not hide it. - - // TODO(jered): Still clearing the uncommitted query here because otherwise - // the page behaves improperly on repeating the same query immediately. This - // behavior was not apparent when we used to Hide() in this case. Find out - // why, and then remove this call or this TODO. - SendBlankQuery(); - return; - } - - if (model_.preview_state() != InstantModel::CUSTOM_NTP_CONTENT) - Hide(); -} - TabContents* InstantController::GetPreviewContents() const { - return loader_.get() ? loader_->preview_contents() : NULL; -} - -void InstantController::Hide() { - // The only time when the preview is not already in the desired NOT_READY - // state and GetPreviewContents() returns NULL is when we are in the commit - // path. In that case, don't change the state just yet; otherwise we may - // cause the preview to hide unnecessarily. Instead, the state will be set - // correctly after the commit is done. - if (GetPreviewContents()) - model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); - - // Clear the first interaction timestamp for later use. - first_interaction_time_ = base::Time(); - - if (GetPreviewContents() && !last_full_text_.empty()) { - // Send a blank query to ask the preview to clear out old results. - SendBlankQuery(); - } -} - -void InstantController::SendBlankQuery() { - last_full_text_.clear(); - last_user_text_.clear(); - loader_->Update(last_full_text_, true); + return loader_ ? loader_->preview_contents() : NULL; } bool InstantController::IsCurrent() const { - return model_.preview_state() == InstantModel::QUERY_RESULTS && - GetPreviewContents() && - loader_->supports_instant() && last_match_was_search_; + return model_.mode().is_search_suggestions() && last_match_was_search_; } -void InstantController::CommitCurrentPreview(InstantCommitType type) { +bool InstantController::CommitIfCurrent(InstantCommitType type) { + if (!IsCurrent()) + return false; + + DVLOG(1) << "CommitIfCurrent"; TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); - if (mode_ == EXTENDED) { + if (extended_enabled_) { // Consider what's happening: // 1. The user has typed a query in the omnibox and committed it (either // by pressing Enter or clicking on the preview). @@ -428,17 +422,17 @@ void InstantController::CommitCurrentPreview(InstantCommitType type) { history::SOURCE_BROWSED, false); } - DeleteLoader(); - preview->web_contents()->GetController().PruneAllButActive(); if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { const TabContents* active_tab = browser_->GetActiveTabContents(); - AddSessionStorageHistogram(mode_, active_tab, preview); + AddSessionStorageHistogram(extended_enabled_, active_tab, preview); preview->web_contents()->GetController().CopyStateFromAndPrune( &active_tab->web_contents()->GetController()); } + DeleteLoader(); + // Browser takes ownership of the preview. browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); @@ -447,128 +441,96 @@ void InstantController::CommitCurrentPreview(InstantCommitType type) { content::Source<content::WebContents>(preview->web_contents()), content::NotificationService::NoDetails()); - model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); + model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); // Try to create another loader immediately so that it is ready for the next // user interaction. CreateDefaultLoader(); + + return true; } -void InstantController::OnAutocompleteLostFocus( - gfx::NativeView view_gaining_focus) { +void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { + DVLOG(1) << "OmniboxLostFocus"; is_omnibox_focused_ = false; - // If there is no preview, nothing to do. - if (!GetPreviewContents()) - return; - - // It's bizarre if custom NTP content disappears when the user focuses - // outside the omnibox. - if (model_.preview_state() == InstantModel::CUSTOM_NTP_CONTENT) + if (!extended_enabled_ && !instant_enabled_) return; - // If the preview is not showing, only need to check for loader staleness. - if (model_.preview_state() == InstantModel::NOT_READY) { - MaybeOnStaleLoader(); + // If the preview isn't showing search suggestions, nothing to do. The check + // for GetPreviewContents() (which normally is redundant, given IsCurrent()) + // is to handle the case when we get here during a commit. + if (!IsCurrent() || !GetPreviewContents()) { + OnStaleLoader(); return; } #if defined(OS_MACOSX) - if (!loader_->IsPointerDownFromActivate()) { - Hide(); - MaybeOnStaleLoader(); - } + if (!loader_->IsPointerDownFromActivate()) + Hide(true); #else - content::RenderWidgetHostView* rwhv = - GetPreviewContents()->web_contents()->GetRenderWidgetHostView(); - if (!view_gaining_focus || !rwhv) { - Hide(); - MaybeOnStaleLoader(); - return; - } - -#if defined(TOOLKIT_VIEWS) - // For views the top level widget is always focused. If the focus change - // originated in views determine the child Widget from the view that is being - // focused. - views::Widget* widget = - views::Widget::GetWidgetForNativeView(view_gaining_focus); - if (widget) { - views::FocusManager* focus_manager = widget->GetFocusManager(); - if (focus_manager && focus_manager->is_changing_focus() && - focus_manager->GetFocusedView() && - focus_manager->GetFocusedView()->GetWidget()) { - view_gaining_focus = - focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); - } - } + if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), + GetPreviewContents()->web_contents())) + CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); + else + Hide(true); #endif +} - gfx::NativeView tab_view = - GetPreviewContents()->web_contents()->GetNativeView(); +void InstantController::OmniboxGotFocus() { + DVLOG(1) << "OmniboxGotFocus"; + is_omnibox_focused_ = true; + if ((extended_enabled_ || instant_enabled_) && !GetPreviewContents()) + CreateDefaultLoader(); +} - // Focus is going to the renderer. - if (rwhv->GetNativeView() == view_gaining_focus || - tab_view == view_gaining_focus) { - - // If the mouse is not down, focus is not going to the renderer. Someone - // else moved focus and we shouldn't commit. - if (!loader_->IsPointerDownFromActivate()) { - Hide(); - MaybeOnStaleLoader(); - } +void InstantController::SearchModeChanged( + const chrome::search::Mode& old_mode, + const chrome::search::Mode& new_mode) { + DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" + << old_mode.mode << " to " << new_mode.origin << ":" + << new_mode.mode; + search_mode_ = new_mode; + if (!extended_enabled_ && !instant_enabled_) return; - } - - // Walk up the view hierarchy. If the view gaining focus is a subview of the - // WebContents view (such as a windowed plugin or http auth dialog), we want - // to keep the preview contents. Otherwise, focus has gone somewhere else, - // such as the JS inspector, and we want to cancel the preview. - gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus; - while (view_gaining_focus_ancestor && - view_gaining_focus_ancestor != tab_view) { - view_gaining_focus_ancestor = - platform_util::GetParent(view_gaining_focus_ancestor); - } - if (view_gaining_focus_ancestor) { - CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); - return; + if (new_mode.is_search_suggestions()) { + // The preview is showing NTP content, but it's not appropriate anymore. + if (model_.mode().is_ntp() && !new_mode.is_origin_ntp()) + Hide(false); + } else { + Hide(true); } - Hide(); - MaybeOnStaleLoader(); -#endif + if (GetPreviewContents() && old_mode.is_ntp() != new_mode.is_ntp() && + extended_enabled_) + loader_->OnActiveTabModeChanged(new_mode.is_ntp()); } -void InstantController::OnAutocompleteGotFocus() { - is_omnibox_focused_ = true; - CreateDefaultLoader(); -} +void InstantController::ActiveTabChanged() { + DVLOG(1) << "ActiveTabChanged"; -void InstantController::OnActiveTabModeChanged(chrome::search::Mode new_mode) { - const bool is_ntp_changed = active_tab_mode_.is_ntp() != new_mode.is_ntp(); - active_tab_mode_ = new_mode; - if (is_ntp_changed && GetPreviewContents()) { - loader_->OnActiveTabModeChanged(new_mode.is_ntp()); - // On navigation away from the NTP, hide custom content. However keep - // the preview shown if searching, since it will soon show a suggestions - // dropdown and hiding it would cause flicker. - if (new_mode.is_default() && - model_.preview_state() == InstantModel::CUSTOM_NTP_CONTENT) - Hide(); - } + // By this time, SearchModeChanged() should've been called, so we only need to + // handle the case when the search mode does NOT change, as in the case of + // going from search_suggestions to search_suggestions (i.e., partial queries + // on both old and new tabs). + if (search_mode_.is_search_suggestions() && + model_.mode().is_search_suggestions()) + Hide(false); } -bool InstantController::commit_on_pointer_release() const { - return GetPreviewContents() && loader_->IsPointerDownFromActivate(); +void InstantController::SetInstantEnabled(bool instant_enabled) { + instant_enabled_ = instant_enabled; + if (!extended_enabled_ && !instant_enabled_) + DeleteLoader(); } void InstantController::SetSuggestions( InstantLoader* loader, const std::vector<InstantSuggestion>& suggestions) { - if (loader_ != loader || model_.preview_state() == InstantModel::NOT_READY) + DVLOG(1) << "SetSuggestions"; + if (loader_ != loader || !search_mode_.is_search_suggestions()) return; InstantSuggestion suggestion; @@ -585,6 +547,8 @@ void InstantController::SetSuggestions( last_verbatim_ = true; last_suggestion_ = InstantSuggestion(); last_match_was_search_ = suggestion.type == INSTANT_SUGGESTION_SEARCH; + DVLOG(1) << "SetReplaceSuggestion: text='" << suggestion.text << "'" + << " type=" << suggestion.type; browser_->SetInstantSuggestion(suggestion); } else { // Suggestion text should be a full URL for URL suggestions, or the @@ -604,8 +568,8 @@ void InstantController::SetSuggestions( // Unicode normalize and case-fold the user text and suggestion. If the // user text is a prefix, suggest the normalized, case-folded completion; // for instance, if the user types 'i' and the suggestion is 'INSTANT', - // suggestion 'nstant'. Otherwise, the user text really isn't a prefix, - // so suggest nothing. + // suggest 'nstant'. Otherwise, the user text really isn't a prefix, so + // suggest nothing. suggestion = InstantSuggestion(); } @@ -613,33 +577,29 @@ void InstantController::SetSuggestions( // Set the suggested text if the suggestion behavior is // INSTANT_COMPLETE_NEVER irrespective of verbatim because in this case - // the suggested text does not get committed if the user presses enter. - if (suggestion.behavior == INSTANT_COMPLETE_NEVER || !last_verbatim_) + // the suggested text does not get committed if the user presses Enter. + if (suggestion.behavior == INSTANT_COMPLETE_NEVER || !last_verbatim_) { + DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" + << " behavior=" << suggestion.behavior << " type=" + << suggestion.type; browser_->SetInstantSuggestion(suggestion); + } } Show(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); } void InstantController::CommitInstantLoader(InstantLoader* loader) { - if (loader_ != loader || - model_.preview_state() != InstantModel::QUERY_RESULTS) - return; - - CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); + if (loader_ == loader) + CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); } void InstantController::ShowInstantPreview(InstantLoader* loader, InstantShownReason reason, int height, InstantSizeUnits units) { - if (loader_ != loader || mode_ != EXTENDED) - return; - - Show(reason, height, units); -} - -void InstantController::InstantLoaderPreviewLoaded(InstantLoader* loader) { + if (loader_ == loader && extended_enabled_) + Show(reason, height, units); } void InstantController::InstantSupportDetermined(InstantLoader* loader, @@ -667,24 +627,17 @@ void InstantController::InstantLoaderContentsFocused(InstantLoader* loader) { #if defined(USE_AURA) // On aura the omnibox only receives a focus lost if we initiate the focus // change. This does that. - if (model_.preview_state() != InstantModel::NOT_READY) + if (!model_.mode().is_default()) browser_->InstantPreviewFocused(); #endif } -InstantController::InstantController(chrome::BrowserInstantController* browser, - Mode mode) - : browser_(browser), - model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - mode_(mode), - last_verbatim_(false), - last_transition_type_(content::PAGE_TRANSITION_LINK), - last_match_was_search_(false), - is_omnibox_focused_(false) { -} - -void InstantController::ResetLoader(const std::string& instant_url, +bool InstantController::ResetLoader(const TemplateURL* template_url, const TabContents* active_tab) { + std::string instant_url; + if (!GetInstantURL(template_url, &instant_url)) + return false; + if (GetPreviewContents() && loader_->instant_url() != instant_url) DeleteLoader(); @@ -693,62 +646,59 @@ void InstantController::ResetLoader(const std::string& instant_url, loader_->Init(); // Ensure the searchbox API has the correct context. - loader_->OnActiveTabModeChanged(active_tab_mode_.is_ntp()); + if (extended_enabled_) + loader_->OnActiveTabModeChanged(search_mode_.is_ntp()); // Reset the loader timer. - stale_loader_timer_.Stop(); stale_loader_timer_.Start( FROM_HERE, base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, &InstantController::OnStaleLoader); } + + return true; } bool InstantController::CreateDefaultLoader() { + // If there's no active tab, the browser is closing. const TabContents* active_tab = browser_->GetActiveTabContents(); - - // We could get here with no active tab if the Browser is closing. if (!active_tab) return false; const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(active_tab->profile())-> GetDefaultSearchProvider(); - const GURL& tab_url = active_tab->web_contents()->GetURL(); - std::string instant_url; - if (!GetInstantURL(template_url, tab_url, &instant_url)) - return false; - ResetLoader(instant_url, active_tab); - return true; + return ResetLoader(template_url, active_tab); } void InstantController::OnStaleLoader() { - // If the loader is showing, do not delete it. It will get deleted the next - // time the autocomplete loses focus. - if (model_.preview_state() != InstantModel::NOT_READY) - return; - - DeleteLoader(); - CreateDefaultLoader(); -} - -void InstantController::MaybeOnStaleLoader() { - if (!stale_loader_timer_.IsRunning()) - OnStaleLoader(); + // If the preview is showing or the omnibox has focus, don't delete the + // loader. It will get refreshed the next time the preview is hidden or the + // omnibox loses focus. + if (!stale_loader_timer_.IsRunning() && !is_omnibox_focused_ && + model_.mode().is_default()) { + DeleteLoader(); + CreateDefaultLoader(); + } } void InstantController::DeleteLoader() { - last_full_text_.clear(); last_user_text_.clear(); + last_full_text_.clear(); last_verbatim_ = false; last_suggestion_ = InstantSuggestion(); last_match_was_search_ = false; + if (!extended_enabled_) + search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; last_omnibox_bounds_ = gfx::Rect(); + stale_loader_timer_.Stop(); url_for_history_ = GURL(); - if (GetPreviewContents()) - model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); first_interaction_time_ = base::Time(); + if (GetPreviewContents()) { + model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); + loader_->CleanupPreviewContents(); + } // Schedule the deletion for later, since we may have gotten here from a call // within a |loader_| method (i.e., it's still on the stack). If we deleted @@ -757,33 +707,57 @@ void InstantController::DeleteLoader() { MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); } +void InstantController::Hide(bool clear_query) { + DVLOG(1) << "Hide: clear_query=" << clear_query; + + // The only time when the preview is not already in the desired MODE_DEFAULT + // state and GetPreviewContents() returns NULL is when we are in the commit + // path. In that case, don't change the state just yet; otherwise we may + // cause the preview to hide unnecessarily. Instead, the state will be set + // correctly after the commit is done. + if (GetPreviewContents()) + model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); + + // Clear the first interaction timestamp for later use. + first_interaction_time_ = base::Time(); + + if (clear_query) { + if (GetPreviewContents() && !last_full_text_.empty()) + loader_->Update(string16(), true); + last_user_text_.clear(); + last_full_text_.clear(); + } + + OnStaleLoader(); +} + void InstantController::Show(InstantShownReason reason, int height, InstantSizeUnits units) { + DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" + << units; + // Must be on NTP to show NTP content. - if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && - !active_tab_mode_.is_ntp()) + if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) return; // Must have updated omnibox after most recent Hide() to show suggestions. if (reason == INSTANT_SHOWN_QUERY_SUGGESTIONS && - model_.preview_state() == InstantModel::NOT_READY) + !search_mode_.is_search_suggestions()) return; // If the preview is being shown because of the first set of suggestions to // arrive for this query editing session, record a histogram value. - if (!first_interaction_time_.is_null() && - model_.preview_state() == InstantModel::AWAITING_SUGGESTIONS) { + if (!first_interaction_time_.is_null() && model_.mode().is_default()) { base::TimeDelta delta = base::Time::Now() - first_interaction_time_; UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); } - model_.SetPreviewState(GetNewPreviewState(reason), height, units); + model_.SetPreviewState(search_mode_, height, units); } void InstantController::SendBoundsToPage() { if (last_omnibox_bounds_ == omnibox_bounds_ || - model_.preview_state() == InstantModel::NOT_READY || !GetPreviewContents() || loader_->IsPointerDownFromActivate()) return; @@ -810,7 +784,6 @@ void InstantController::SendBoundsToPage() { } bool InstantController::GetInstantURL(const TemplateURL* template_url, - const GURL& tab_url, std::string* instant_url) const { CommandLine* command_line = CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kInstantURL)) { @@ -833,7 +806,7 @@ bool InstantController::GetInstantURL(const TemplateURL* template_url, // Extended mode should always use HTTPS. TODO(sreeram): This section can be // removed if TemplateURLs supported "https://{google:host}/..." instead of // only supporting "{google:baseURL}...". - if (mode_ == EXTENDED) { + if (extended_enabled_) { GURL url_obj(*instant_url); if (!url_obj.is_valid()) return false; diff --git a/chrome/browser/instant/instant_controller.h b/chrome/browser/instant/instant_controller.h index 73bdedf..c6def6c 100644 --- a/chrome/browser/instant/instant_controller.h +++ b/chrome/browser/instant/instant_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,10 +10,10 @@ #include <vector> #include "base/basictypes.h" -#include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "base/string16.h" +#include "base/time.h" #include "base/timer.h" #include "chrome/browser/instant/instant_commit_type.h" #include "chrome/browser/instant/instant_model.h" @@ -27,8 +27,6 @@ struct AutocompleteMatch; class AutocompleteProvider; class InstantLoader; -class PrefService; -class Profile; class TabContents; class TemplateURL; @@ -36,50 +34,14 @@ namespace chrome { class BrowserInstantController; } -// InstantController maintains a WebContents that is intended to give a -// preview of search results. InstantController is owned by Browser via +// InstantController maintains a WebContents that is intended to give a preview +// of search suggestions and results. InstantController is owned by Browser via // BrowserInstantController. -// -// At any time the WebContents maintained by InstantController may be hidden -// from view by way of Hide(), which may result in a change in the model's -// display state and subsequent change in model observers. Similarly, the -// preview may be committed at any time by invoking CommitCurrentPreview(), -// which results in CommitInstant() being invoked on the browser. class InstantController { public: - // InstantController may operate in one of these modes: - // EXTENDED: The default search engine is preloaded when the omnibox gets - // focus. Queries are issued as the user types. Predicted queries are - // inline autocompleted into the omnibox. Previews of search results - // as well as predicted URLs are shown. Search suggestions are rendered - // within the search results preview. - // INSTANT: Same as EXTENDED, without URL previews. Search suggestions are - // rendered by the omnibox drop down, and not by the preview page. - // DISABLED: Instant is disabled. - enum Mode { - EXTENDED, - INSTANT, - DISABLED, - }; - - virtual ~InstantController(); - - // Creates a new InstantController. Caller owns the returned object. The - // |profile| pointer is not cached, so the underlying profile object need not - // live beyond this call. ***NOTE***: May return NULL, which means that - // Instant is disabled in this profile. - static InstantController* CreateInstant( - Profile* profile, - chrome::BrowserInstantController* browser); - - // Returns true if Instant is enabled and supports the extended API. - static bool IsExtendedAPIEnabled(Profile* profile); - - // Returns true if Instant is enabled in a visible, preview-showing mode. - static bool IsInstantEnabled(Profile* profile); - - // Registers Instant related preferences. - static void RegisterUserPrefs(PrefService* prefs); + InstantController(chrome::BrowserInstantController* browser, + bool extended_enabled); + ~InstantController(); // Invoked as the user types into the omnibox. |user_text| is what the user // has typed. |full_text| is what the omnibox is showing. These may differ if @@ -90,7 +52,9 @@ class InstantController { bool Update(const AutocompleteMatch& match, const string16& user_text, const string16& full_text, - bool verbatim); + bool verbatim, + bool user_input_in_progress, + bool omnibox_popup_is_open); // Sets the bounds of the omnibox dropdown, in screen coordinates. void SetOmniboxBounds(const gfx::Rect& bounds); @@ -104,41 +68,35 @@ class InstantController { // handled the key press. bool OnUpOrDownKeyPressed(int count); - // Called when the user presses escape while editing omnibox text. - void OnEscapeKeyPressed(); - // The preview TabContents. May be NULL if ReleasePreviewContents() has been // called, with no subsequent successful call to Update(). InstantController // retains ownership of the object. TabContents* GetPreviewContents() const; - // Hides the preview, but doesn't destroy it, in hopes it can be subsequently - // reused. The preview will not be used until a call to Update() succeeds. - void Hide(); - - // Returns true if the Instant preview can be committed now. This can be true - // even if the preview is not showing yet, because we can commit as long as - // we've processed the last Update() and we know the loader supports Instant. + // Returns true if the Instant preview can be committed now. bool IsCurrent() const; - // Commits the preview. Calls CommitInstant() on the browser. - void CommitCurrentPreview(InstantCommitType type); + // If the preview is showing search results, commits the preview, calling + // CommitInstant() on the browser, and returns true. Else, returns false. + bool CommitIfCurrent(InstantCommitType type); - // The autocomplete edit that was initiating the current Instant session has - // lost focus. Commit or discard the preview accordingly. - void OnAutocompleteLostFocus(gfx::NativeView view_gaining_focus); + // The omnibox has lost focus. Commit or discard the preview accordingly. + void OmniboxLostFocus(gfx::NativeView view_gaining_focus); - // The autocomplete edit has gained focus. Preload the Instant URL of the - // default search engine, in anticipation of the user typing a query. - void OnAutocompleteGotFocus(); + // The omnibox has gained focus. Preload the default search engine, in + // anticipation of the user typing a query. + void OmniboxGotFocus(); // The search mode in the active tab has changed. Pass the message down to // the loader which will notify the renderer. - void OnActiveTabModeChanged(chrome::search::Mode new_mode); + void SearchModeChanged(const chrome::search::Mode& old_mode, + const chrome::search::Mode& new_mode); - // Returns whether the preview will be committed when the mouse or touch - // pointer is released. - bool commit_on_pointer_release() const; + // The user switched tabs. Hide the preview if needed. + void ActiveTabChanged(); + + // Sets whether Instant should show result previews. + void SetInstantEnabled(bool instant_enabled); // Returns the transition type of the last AutocompleteMatch passed to Update. content::PageTransition last_transition_type() const { @@ -160,9 +118,6 @@ class InstantController { int height, InstantSizeUnits units); - // Invoked by InstantLoader to notify that the Instant URL completed loading. - void InstantLoaderPreviewLoaded(InstantLoader* loader); - // Invoked by InstantLoader when it has determined whether or not the page // supports the Instant API. void InstantSupportDetermined(InstantLoader* loader, bool supports_instant); @@ -183,11 +138,11 @@ class InstantController { private: FRIEND_TEST_ALL_PREFIXES(InstantTest, InstantLoaderRefresh); - InstantController(chrome::BrowserInstantController* browser, Mode mode); - - // Creates a new loader if necessary (for example, if the |instant_url| has - // changed since the last time we created the loader). - void ResetLoader(const std::string& instant_url, + // Creates a new loader if necessary, using the instant_url property of the + // |template_url| (for example, if the Instant URL has changed since the last + // time the loader was created). Returns false if the |template_url| doesn't + // have a valid Instant URL; true otherwise. + bool ResetLoader(const TemplateURL* template_url, const TabContents* active_tab); // Ensures that the |loader_| uses the default Instant URL, recreating it if @@ -195,23 +150,23 @@ class InstantController { // determined or the active tab is NULL (browser is shutting down). bool CreateDefaultLoader(); - // If the |loader_| is not showing, it is deleted and recreated. Else the - // refresh is skipped and the next refresh is scheduled. + // Called when the |loader_| might be stale. If it's actually stale, and the + // omnibox doesn't have focus, and the preview isn't showing, the |loader_| is + // deleted and recreated. Else the refresh is skipped. void OnStaleLoader(); - // Calls OnStaleLoader if |stale_loader_timer_| is not running. - void MaybeOnStaleLoader(); - // Destroys the |loader_| and its preview contents. void DeleteLoader(); + // Hide the preview. If |clear_query| is true, clears query text and sends a + // an onchange event (with blank query) to the preview, telling it to clear + // out results for any old queries. + void Hide(bool clear_query); + // Counterpart to Hide(). Asks the |browser_| to display the preview with // the given |height|. void Show(InstantShownReason reason, int height, InstantSizeUnits units); - // Send a blank query to clear out results for last search. - void SendBlankQuery(); - // Send the omnibox dropdown bounds to the page. void SendBoundsToPage(); @@ -220,24 +175,25 @@ class InstantController { // Note: If the command-line switch kInstantURL is set, this method uses its // value for |instant_url| and returns true without examining |template_url|. bool GetInstantURL(const TemplateURL* template_url, - const GURL& tab_url, std::string* instant_url) const; chrome::BrowserInstantController* const browser_; + // Whether the extended API and regular API are enabled. If both are false, + // Instant is effectively disabled. + const bool extended_enabled_; + bool instant_enabled_; + InstantModel model_; scoped_ptr<InstantLoader> loader_; - // See the enum description above. - const Mode mode_; + // The most recent user_text passed to Update(). + string16 last_user_text_; // The most recent full_text passed to Update(). string16 last_full_text_; - // The most recent user_text passed to Update(). - string16 last_user_text_; - // The most recent verbatim passed to Update(). bool last_verbatim_; @@ -255,7 +211,7 @@ class InstantController { bool is_omnibox_focused_; // The search model mode for the active tab. - chrome::search::Mode active_tab_mode_; + chrome::search::Mode search_mode_; // Current omnibox bounds. gfx::Rect omnibox_bounds_; diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc index 47681aa..9f2b82b 100644 --- a/chrome/browser/instant/instant_loader.cc +++ b/chrome/browser/instant/instant_loader.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,7 +20,6 @@ #include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" namespace { @@ -30,12 +29,14 @@ int kUserDataKey; class InstantLoaderUserData : public base::SupportsUserData::Data { public: explicit InstantLoaderUserData(InstantLoader* loader) : loader_(loader) {} - virtual ~InstantLoaderUserData() {} InstantLoader* loader() const { return loader_; } private: - InstantLoader* loader_; + ~InstantLoaderUserData() {} + + InstantLoader* const loader_; + DISALLOW_COPY_AND_ASSIGN(InstantLoaderUserData); }; @@ -55,18 +56,19 @@ class InstantLoader::WebContentsDelegateImpl return is_pointer_down_from_activate_; } - bool has_shown_custom_ntp_content() const { - return has_shown_custom_ntp_content_; - } + // Start observing |web_contents| instead of whatever is currently being + // observed. If |web_contents| is NULL, effectively stops observing. + void ObserveContents(content::WebContents* web_contents); - // ConstrainedWindowTabHelperDelegate: + private: + // Overridden from ConstrainedWindowTabHelperDelegate: virtual bool ShouldFocusConstrainedWindow() OVERRIDE; - // CoreTabHelperDelegate: + // Overridden from CoreTabHelperDelegate: virtual void SwapTabContents(content::WebContents* old_contents, content::WebContents* new_contents) OVERRIDE; - // content::WebContentsDelegate: + // Overridden from content::WebContentsDelegate: virtual bool ShouldSuppressDialogs() OVERRIDE; virtual bool ShouldFocusPageAfterCrash() OVERRIDE; virtual void LostCapture() OVERRIDE; @@ -77,12 +79,11 @@ class InstantLoader::WebContentsDelegateImpl virtual void HandleMouseDown() OVERRIDE; virtual void HandleMouseUp() OVERRIDE; virtual void HandlePointerActivate() OVERRIDE; - virtual void HandleGestureBegin() OVERRIDE; virtual void HandleGestureEnd() OVERRIDE; virtual void DragEnded() OVERRIDE; virtual bool OnGoToEntryOffset(int offset) OVERRIDE; - // content::WebContentsObserver: + // Overridden from content::WebContentsObserver: virtual void DidFinishLoad( int64 frame_id, const GURL& validated_url, @@ -90,7 +91,6 @@ class InstantLoader::WebContentsDelegateImpl content::RenderViewHost* render_view_host) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - private: // Message from renderer indicating the page has suggestions. void OnSetSuggestions(int page_id, const std::vector<InstantSuggestion>& suggestions); @@ -112,18 +112,18 @@ class InstantLoader::WebContentsDelegateImpl // True if the mouse or a touch pointer is down from an activate. bool is_pointer_down_from_activate_; - // True if the preview has shown custom NTP content. - bool has_shown_custom_ntp_content_; - DISALLOW_COPY_AND_ASSIGN(WebContentsDelegateImpl); }; InstantLoader::WebContentsDelegateImpl::WebContentsDelegateImpl( InstantLoader* loader) - : content::WebContentsObserver(loader->preview_contents_->web_contents()), - loader_(loader), - is_pointer_down_from_activate_(false), - has_shown_custom_ntp_content_(false) { + : loader_(loader), + is_pointer_down_from_activate_(false) { +} + +void InstantLoader::WebContentsDelegateImpl::ObserveContents( + content::WebContents* web_contents) { + Observe(web_contents); } bool InstantLoader::WebContentsDelegateImpl::ShouldFocusConstrainedWindow() { @@ -179,9 +179,6 @@ void InstantLoader::WebContentsDelegateImpl::HandlePointerActivate() { is_pointer_down_from_activate_ = true; } -void InstantLoader::WebContentsDelegateImpl::HandleGestureBegin() { -} - void InstantLoader::WebContentsDelegateImpl::HandleGestureEnd() { CommitFromPointerReleaseIfNecessary(); } @@ -202,11 +199,8 @@ void InstantLoader::WebContentsDelegateImpl::DidFinishLoad( const GURL& validated_url, bool is_main_frame, content::RenderViewHost* render_view_host) { - if (is_main_frame) { - if (!loader_->supports_instant_) - Send(new ChromeViewMsg_DetermineIfPageSupportsInstant(routing_id())); - loader_->controller_->InstantLoaderPreviewLoaded(loader_); - } + if (is_main_frame && !loader_->supports_instant_) + Send(new ChromeViewMsg_DetermineIfPageSupportsInstant(routing_id())); } bool InstantLoader::WebContentsDelegateImpl::OnMessageReceived( @@ -258,8 +252,6 @@ void InstantLoader::WebContentsDelegateImpl::OnShowInstantPreview( GetController().GetActiveEntry(); if (entry && page_id == entry->GetPageID()) { MaybeSetAndNotifyInstantSupportDetermined(true); - if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT) - has_shown_custom_ntp_content_ = true; loader_->controller_->ShowInstantPreview(loader_, reason, height, units); } } @@ -275,19 +267,10 @@ void InstantLoader::WebContentsDelegateImpl void InstantLoader::WebContentsDelegateImpl ::MaybeSetAndNotifyInstantSupportDetermined(bool supports_instant) { // If we already determined that the loader supports Instant, nothing to do. - if (loader_->supports_instant_) - return; - - // If the page doesn't support the Instant API, InstantController schedules - // the loader for destruction. Stop sending the controller any more messages, - // by severing the connection from the WebContents to us (its delegate). - if (!supports_instant) { - loader_->preview_contents_->web_contents()->SetDelegate(NULL); - Observe(NULL); + if (!loader_->supports_instant_) { + loader_->supports_instant_ = supports_instant; + loader_->controller_->InstantSupportDetermined(loader_, supports_instant); } - - loader_->supports_instant_ = supports_instant; - loader_->controller_->InstantSupportDetermined(loader_, supports_instant); } // InstantLoader --------------------------------------------------------------- @@ -304,6 +287,8 @@ InstantLoader::InstantLoader(InstantController* controller, const std::string& instant_url, const TabContents* tab_contents) : controller_(controller), + preview_delegate_(new WebContentsDelegateImpl( + ALLOW_THIS_IN_INITIALIZER_LIST(this))), preview_contents_( TabContents::Factory::CreateTabContents( content::WebContents::CreateWithSessionStorage( @@ -316,14 +301,13 @@ InstantLoader::InstantLoader(InstantController* controller, } InstantLoader::~InstantLoader() { - if (preview_contents()) - preview_contents_->web_contents()->SetDelegate(NULL); } void InstantLoader::Init() { SetupPreviewContents(); // This HTTP header and value are set on loads that originate from instant. - const char* const kInstantHeader = "X-Purpose: Instant"; + const char kInstantHeader[] = "X-Purpose: Instant"; + DVLOG(1) << "LoadURL: " << instant_url_; preview_contents_->web_contents()->GetController().LoadURL(GURL(instant_url_), content::Referrer(), content::PAGE_TRANSITION_GENERATED, kInstantHeader); preview_contents_->web_contents()->WasHidden(); @@ -362,8 +346,8 @@ void InstantLoader::OnUpOrDownKeyPressed(int count) { void InstantLoader::OnActiveTabModeChanged(bool active_tab_is_ntp) { content::RenderViewHost* rvh = preview_contents_->web_contents()->GetRenderViewHost(); - rvh->Send(new ChromeViewMsg_SearchBoxActiveTabModeChanged( - rvh->GetRoutingID(), active_tab_is_ntp)); + rvh->Send(new ChromeViewMsg_SearchBoxActiveTabModeChanged(rvh->GetRoutingID(), + active_tab_is_ntp)); } void InstantLoader::DidNavigate( @@ -380,16 +364,37 @@ TabContents* InstantLoader::ReleasePreviewContents(InstantCommitType type, else rvh->Send(new ChromeViewMsg_SearchBoxSubmit(rvh->GetRoutingID(), text)); CleanupPreviewContents(); - preview_contents_->web_contents()->RemoveUserData(&kUserDataKey); return preview_contents_.release(); } -bool InstantLoader::IsPointerDownFromActivate() const { - return preview_delegate_->is_pointer_down_from_activate(); +void InstantLoader::CleanupPreviewContents() { + content::WebContents* old_contents = preview_contents_->web_contents(); + old_contents->RemoveUserData(&kUserDataKey); + old_contents->SetDelegate(NULL); + preview_delegate_->ObserveContents(NULL); + + BlockedContentTabHelper::FromWebContents(old_contents)-> + SetAllContentsBlocked(false); + ConstrainedWindowTabHelper::FromWebContents(old_contents)->set_delegate(NULL); + TabSpecificContentSettings::FromWebContents(old_contents)-> + SetPopupsBlocked(false); + CoreTabHelper::FromWebContents(old_contents)->set_delegate(NULL); + if (ThumbnailTabHelper* thumbnail_tab_helper = + ThumbnailTabHelper::FromWebContents(old_contents)) + thumbnail_tab_helper->set_enabled(true); + +#if defined(OS_MACOSX) + if (content::RenderWidgetHostView* rwhv = + old_contents->GetRenderWidgetHostView()) + rwhv->SetTakesFocusOnlyOnMouseDown(false); + registrar_.Remove(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, + content::Source<content::NavigationController>( + &old_contents->GetController())); +#endif } -bool InstantLoader::HasShownCustomNTPContent() const { - return preview_delegate_->has_shown_custom_ntp_content(); +bool InstantLoader::IsPointerDownFromActivate() const { + return preview_delegate_->is_pointer_down_from_activate(); } void InstantLoader::Observe(int type, @@ -409,9 +414,9 @@ void InstantLoader::Observe(int type, void InstantLoader::SetupPreviewContents() { content::WebContents* new_contents = preview_contents_->web_contents(); new_contents->SetUserData(&kUserDataKey, new InstantLoaderUserData(this)); - preview_delegate_.reset(new WebContentsDelegateImpl(this)); WebContentsDelegateImpl* new_delegate = preview_delegate_.get(); new_contents->SetDelegate(new_delegate); + new_delegate->ObserveContents(new_contents); // Disable popups and such (mainly to avoid losing focus and reverting the // preview prematurely). @@ -422,9 +427,8 @@ void InstantLoader::SetupPreviewContents() { TabSpecificContentSettings::FromWebContents(new_contents)-> SetPopupsBlocked(true); CoreTabHelper::FromWebContents(new_contents)->set_delegate(new_delegate); - ThumbnailTabHelper* thumbnail_tab_helper = - ThumbnailTabHelper::FromWebContents(new_contents); - if (thumbnail_tab_helper) + if (ThumbnailTabHelper* thumbnail_tab_helper = + ThumbnailTabHelper::FromWebContents(new_contents)) thumbnail_tab_helper->set_enabled(false); #if defined(OS_MACOSX) @@ -440,32 +444,6 @@ void InstantLoader::SetupPreviewContents() { #endif } -void InstantLoader::CleanupPreviewContents() { - content::WebContents* old_contents = preview_contents_->web_contents(); - old_contents->SetDelegate(NULL); - preview_delegate_.reset(); - - BlockedContentTabHelper::FromWebContents(old_contents)-> - SetAllContentsBlocked(false); - ConstrainedWindowTabHelper::FromWebContents(old_contents)->set_delegate(NULL); - TabSpecificContentSettings::FromWebContents(old_contents)-> - SetPopupsBlocked(false); - CoreTabHelper::FromWebContents(old_contents)->set_delegate(NULL); - ThumbnailTabHelper* thumbnail_tab_helper = - ThumbnailTabHelper::FromWebContents(old_contents); - if (thumbnail_tab_helper) - thumbnail_tab_helper->set_enabled(true); - -#if defined(OS_MACOSX) - if (content::RenderWidgetHostView* rwhv = - old_contents->GetRenderWidgetHostView()) - rwhv->SetTakesFocusOnlyOnMouseDown(false); - registrar_.Remove(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, - content::Source<content::NavigationController>( - &old_contents->GetController())); -#endif -} - void InstantLoader::ReplacePreviewContents(content::WebContents* old_contents, content::WebContents* new_contents) { DCHECK_EQ(old_contents, preview_contents_->web_contents()); diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h index 1f52b16..cf52b68 100644 --- a/chrome/browser/instant/instant_loader.h +++ b/chrome/browser/instant/instant_loader.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,10 +6,10 @@ #define CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ #include <string> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/string16.h" #include "chrome/browser/history/history_types.h" @@ -22,8 +22,6 @@ class InstantController; class TabContents; namespace content { -class NotificationDetails; -class NotificationSource; class WebContents; } @@ -89,6 +87,10 @@ class InstantLoader : public content::NotificationObserver { TabContents* ReleasePreviewContents(InstantCommitType type, const string16& text) WARN_UNUSED_RESULT; + // Severs delegate and observer connections, resets popup blocking, etc., on + // the |preview_contents_|. + void CleanupPreviewContents(); + // The preview TabContents. The loader retains ownership. This will be // non-NULL until ReleasePreviewContents() is called. TabContents* preview_contents() const { return preview_contents_.get(); } @@ -112,31 +114,28 @@ class InstantLoader : public content::NotificationObserver { // preview content. bool IsPointerDownFromActivate() const; - // Returns true iff the current preview page has shown custom NTP content. - bool HasShownCustomNTPContent() const; + private: + class WebContentsDelegateImpl; - // content::NotificationObserver: + // Overridden from content::NotificationObserver: virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - private: - class WebContentsDelegateImpl; - void SetupPreviewContents(); - void CleanupPreviewContents(); void ReplacePreviewContents(content::WebContents* old_contents, content::WebContents* new_contents); InstantController* const controller_; + // Delegate of the preview WebContents. Used when the user does some gesture + // on the WebContents and it needs to be activated. This MUST be defined above + // |preview_contents_| so that the delegate can outlive the WebContents. + scoped_ptr<WebContentsDelegateImpl> preview_delegate_; + // See comments on the getter above. scoped_ptr<TabContents> preview_contents_; - // Delegate of the preview WebContents. Used to detect when the user does some - // gesture on the WebContents and the preview needs to be activated. - scoped_ptr<WebContentsDelegateImpl> preview_delegate_; - // See comments on the getter above. bool supports_instant_; diff --git a/chrome/browser/instant/instant_model.cc b/chrome/browser/instant/instant_model.cc index 6d62217..bafad5a 100644 --- a/chrome/browser/instant/instant_model.cc +++ b/chrome/browser/instant/instant_model.cc @@ -8,8 +8,7 @@ #include "chrome/browser/instant/instant_model_observer.h" InstantModel::InstantModel(InstantController* controller) - : preview_state_(NOT_READY), - height_(0), + : height_(0), height_units_(INSTANT_SIZE_PIXELS), preview_contents_(NULL), controller_(controller) { @@ -18,15 +17,20 @@ InstantModel::InstantModel(InstantController* controller) InstantModel::~InstantModel() { } -void InstantModel::SetPreviewState(PreviewState preview_state, +void InstantModel::SetPreviewState(const chrome::search::Mode& mode, int height, InstantSizeUnits height_units) { - if (preview_state_ == preview_state && - height_ == height && - height_units_ == height_units) + if (mode_.mode == mode.mode && height_ == height && + height_units_ == height_units) { + // Mode::mode hasn't changed, but perhaps bits that we ignore (such as + // Mode::origin) have. Update |mode_| anyway, so it's consistent with the + // argument (so InstantModel::mode() doesn't return something unexpected). + mode_ = mode; return; + } - preview_state_ = preview_state; + DVLOG(1) << "SetPreviewState: " << mode_.mode << " to " << mode.mode; + mode_ = mode; height_ = height; height_units_ = height_units; @@ -55,7 +59,3 @@ void InstantModel::AddObserver(InstantModelObserver* observer) const { void InstantModel::RemoveObserver(InstantModelObserver* observer) const { observers_.RemoveObserver(observer); } - -bool InstantModel::HasObserver(InstantModelObserver* observer) const { - return observers_.HasObserver(observer); -} diff --git a/chrome/browser/instant/instant_model.h b/chrome/browser/instant/instant_model.h index dd7306a..036ca42 100644 --- a/chrome/browser/instant/instant_model.h +++ b/chrome/browser/instant/instant_model.h @@ -1,11 +1,13 @@ // Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + #ifndef CHROME_BROWSER_INSTANT_INSTANT_MODEL_H_ #define CHROME_BROWSER_INSTANT_INSTANT_MODEL_H_ #include "base/basictypes.h" #include "base/observer_list.h" +#include "chrome/browser/ui/search/search_types.h" #include "chrome/common/instant_types.h" class InstantController; @@ -16,49 +18,37 @@ class TabContents; // layout of the Instant preview. class InstantModel { public: - enum PreviewState { - // Contents are stale. - NOT_READY, - - // Waiting for suggestions in response to the first omnibox interaction. - AWAITING_SUGGESTIONS, - - // Showing search results and suggestions. - QUERY_RESULTS, - - // Showing custom NTP content. - CUSTOM_NTP_CONTENT, - }; - explicit InstantModel(InstantController* controller); ~InstantModel(); - void SetPreviewState(PreviewState preview_state, - int height, - InstantSizeUnits height_units); - PreviewState preview_state() const { return preview_state_; } + // InstantModel only uses Mode::mode internally. Other parts of Mode, such as + // Mode::origin, may have arbitrary values, and should be ignored. + const chrome::search::Mode& mode() const { return mode_; } int height() const { return height_; } InstantSizeUnits height_units() const { return height_units_; } + void SetPreviewState(const chrome::search::Mode& mode, + int height, + InstantSizeUnits height_units); + void SetPreviewContents(TabContents* preview_contents); TabContents* GetPreviewContents() const; - // Add, remove, check observers. + // Add and remove observers. void AddObserver(InstantModelObserver* observer) const; void RemoveObserver(InstantModelObserver* observer) const; - bool HasObserver(InstantModelObserver* observer) const; private: - PreviewState preview_state_; + chrome::search::Mode mode_; int height_; InstantSizeUnits height_units_; - // Weak. Remembers the last set preview contents to detect changes. - // Actual preview contents is fetched from the |controller_| as this - // may not always reflect the actual preview in effect. + // Weak. Remembers the last set preview contents to detect changes. Actual + // preview contents is fetched from the |controller_| as this may not always + // reflect the actual preview in effect. TabContents* preview_contents_; - // Weak. The controller currently holds some model state. + // Weak. The controller currently holds some model state. // TODO(dhollowa): Remove this, transfer all model state to InstantModel. InstantController* const controller_; diff --git a/chrome/browser/instant/instant_model_observer.h b/chrome/browser/instant/instant_model_observer.h index dcefdc1..1985fcc 100644 --- a/chrome/browser/instant/instant_model_observer.h +++ b/chrome/browser/instant/instant_model_observer.h @@ -5,20 +5,17 @@ #ifndef CHROME_BROWSER_INSTANT_INSTANT_MODEL_OBSERVER_H_ #define CHROME_BROWSER_INSTANT_INSTANT_MODEL_OBSERVER_H_ -#include "chrome/common/instant_types.h" - class InstantModel; // This class defines the observer interface for the |InstantModel|. class InstantModelObserver { public: - // Informs the observer that the preview state has has changed. - // This can mean the model state has changed, or the contents of the - // preview. + // Informs the observer that the preview state has changed. This can mean + // either the model state changed or the contents of the preview changed. virtual void PreviewStateChanged(const InstantModel& model) = 0; protected: - virtual ~InstantModelObserver() {} + ~InstantModelObserver() {} }; #endif // CHROME_BROWSER_INSTANT_INSTANT_MODEL_OBSERVER_H_ diff --git a/chrome/browser/instant/instant_preview_controller.cc b/chrome/browser/instant/instant_preview_controller.cc index 3283742d..a728fc81 100644 --- a/chrome/browser/instant/instant_preview_controller.cc +++ b/chrome/browser/instant/instant_preview_controller.cc @@ -4,36 +4,16 @@ #include "chrome/browser/instant/instant_preview_controller.h" -#include "chrome/browser/instant/instant_model.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_instant_controller.h" -#include "chrome/common/chrome_notification_types.h" -#include "content/public/browser/notification_service.h" InstantPreviewController::InstantPreviewController(Browser* browser) : browser_(browser) { - registrar_.Add(this, chrome::NOTIFICATION_BROWSER_INSTANT_RESET, - content::NotificationService::AllSources()); - ResetInstant(); + if (browser_->instant_controller()) + browser_->instant_controller()->instant()->model()->AddObserver(this); } InstantPreviewController::~InstantPreviewController() { - InstantController* instant = browser_->instant_controller()->instant(); - if (instant) - instant->model()->RemoveObserver(this); -} - -void InstantPreviewController::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_BROWSER_INSTANT_RESET, type); - ResetInstant(); -} - -void InstantPreviewController::ResetInstant() { - InstantController* instant = browser_->instant_controller()->instant(); - if (instant && !instant->model()->HasObserver(this)) - instant->model()->AddObserver(this); + if (browser_->instant_controller()) + browser_->instant_controller()->instant()->model()->RemoveObserver(this); } diff --git a/chrome/browser/instant/instant_preview_controller.h b/chrome/browser/instant/instant_preview_controller.h index 9118156..e90e2b6 100644 --- a/chrome/browser/instant/instant_preview_controller.h +++ b/chrome/browser/instant/instant_preview_controller.h @@ -7,36 +7,21 @@ #include "base/compiler_specific.h" #include "chrome/browser/instant/instant_model_observer.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" class Browser; class InstantModel; // Abstract base class for platform-specific Instant preview controllers. -class InstantPreviewController : public InstantModelObserver, - public content::NotificationObserver { - public: +class InstantPreviewController : public InstantModelObserver { + protected: explicit InstantPreviewController(Browser* browser); virtual ~InstantPreviewController(); - // Overridden from InstantModelObserver: - virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE = 0; - - // Overridden from content::NotificationObserver: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - - protected: Browser* const browser_; private: - void ResetInstant(); - - content::NotificationRegistrar registrar_; - - DISALLOW_COPY_AND_ASSIGN(InstantPreviewController); + // Overridden from InstantModelObserver: + virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE = 0; }; #endif // CHROME_BROWSER_INSTANT_INSTANT_PREVIEW_CONTROLLER_H_ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 8ec5f38..e476069 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,7 +26,6 @@ #include "chrome/browser/geolocation/geolocation_prefs.h" #include "chrome/browser/google/google_url_tracker.h" #include "chrome/browser/google/google_url_tracker_factory.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/intents/web_intents_util.h" #include "chrome/browser/intranet_redirect_detector.h" #include "chrome/browser/managed_mode/managed_mode.h" @@ -58,6 +57,7 @@ #include "chrome/browser/task_manager/task_manager.h" #include "chrome/browser/translate/translate_prefs.h" #include "chrome/browser/ui/alternate_error_tab_observer.h" +#include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/browser/ui/browser_ui_prefs.h" #include "chrome/browser/ui/network_profile_bubble.h" #include "chrome/browser/ui/prefs/prefs_tab_helper.h" @@ -234,7 +234,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { GAIAInfoUpdateService::RegisterUserPrefs(user_prefs); HostContentSettingsMap::RegisterUserPrefs(user_prefs); IncognitoModePrefs::RegisterUserPrefs(user_prefs); - InstantController::RegisterUserPrefs(user_prefs); + BrowserInstantController::RegisterUserPrefs(user_prefs); MediaCaptureDevicesDispatcher::RegisterUserPrefs(user_prefs); NetPrefObserver::RegisterPrefs(user_prefs); NewTabUI::RegisterUserPrefs(user_prefs); diff --git a/chrome/browser/search_engines/search_terms_data.cc b/chrome/browser/search_engines/search_terms_data.cc index 49c12b3..b623fef 100644 --- a/chrome/browser/search_engines/search_terms_data.cc +++ b/chrome/browser/search_engines/search_terms_data.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,8 +9,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/google/google_url_tracker.h" #include "chrome/browser/google/google_util.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_instant_controller.h" +#include "chrome/browser/ui/search/search.h" #include "content/public/browser/browser_thread.h" #include "googleurl/src/gurl.h" @@ -111,9 +112,9 @@ string16 UIThreadSearchTermsData::GetRlzParameterValue() const { std::string UIThreadSearchTermsData::InstantEnabledParam() const { DCHECK(!BrowserThread::IsWellKnownThread(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (InstantController::IsExtendedAPIEnabled(profile_)) + if (chrome::search::IsInstantExtendedAPIEnabled(profile_)) return std::string(google_util::kInstantExtendedAPIParam) + "=1&"; - if (InstantController::IsInstantEnabled(profile_)) + if (chrome::BrowserInstantController::IsInstantEnabled(profile_)) return "ion=1&"; return std::string(); } diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 3449325..f01f2e3 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,7 +28,6 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/favicon/favicon_tab_helper.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/profiles/profile.h" @@ -284,7 +283,7 @@ TaskManagerTabContentsResource::TaskManagerTabContentsResource( } for (BrowserList::const_iterator i = BrowserList::begin(); i != BrowserList::end(); ++i) { - if ((*i)->instant_controller()->instant() && + if ((*i)->instant_controller() && (*i)->instant_controller()->instant()->GetPreviewContents() == tab_contents_) { is_instant_preview_ = true; diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index ffd3bdf..78b4d3b8 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -414,7 +414,8 @@ Browser::Browser(const CreateParams& params) encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector, profile_->GetPrefs(), NULL); - instant_controller_.reset(new chrome::BrowserInstantController(this)); + if (is_type_tabbed()) + instant_controller_.reset(new chrome::BrowserInstantController(this)); #if 0 // Disabled for M22. See http://crbug.com/144326. @@ -1150,6 +1151,10 @@ void Browser::ActiveTabChanged(WebContents* old_contents, } UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH); + + // This needs to be called after UpdateSearchState(). + if (instant_controller_) + instant_controller_->ActiveTabChanged(); } void Browser::TabMoved(WebContents* contents, @@ -1211,6 +1216,10 @@ void Browser::TabStripEmpty() { // still present. MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr())); + + // Instant may have visible WebContents that need to be detached before the + // window system closes. + instant_controller_.reset(); } bool Browser::PreHandleKeyboardEvent(content::WebContents* source, diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index a718b33..e0acc52 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -426,7 +426,8 @@ void OpenCurrentURL(Browser* browser) { WindowOpenDisposition open_disposition = location_bar->GetWindowOpenDisposition(); - if (browser->instant_controller()->OpenInstant(open_disposition)) + if (browser->instant_controller() && + browser->instant_controller()->OpenInstant(open_disposition)) return; GURL url(location_bar->GetInputString()); diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc index e58bcb2..f8fd4f5 100644 --- a/chrome/browser/ui/browser_instant_controller.cc +++ b/chrome/browser/ui/browser_instant_controller.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,38 +6,23 @@ #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/omnibox/location_bar.h" +#include "chrome/browser/ui/search/search.h" #include "chrome/browser/ui/search/search_model.h" #include "chrome/browser/ui/search/search_tab_helper.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/pref_names.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" -namespace { - -// Returns true iff the search model for |tab| is in an NTP state, that is, a -// state in which the Instant overlay may be showing custom NTP content in -// EXTENDED mode. -bool IsSearchModelNTP(content::WebContents* tab) { - if (!tab) - return false; - chrome::search::SearchModel* model = - chrome::search::SearchTabHelper::FromWebContents(tab)->model(); - return model && model->mode().is_ntp(); -} - -} // namespace - namespace chrome { //////////////////////////////////////////////////////////////////////////////// @@ -45,23 +30,34 @@ namespace chrome { BrowserInstantController::BrowserInstantController(Browser* browser) : browser_(browser), + instant_(ALLOW_THIS_IN_INITIALIZER_LIST(this), + chrome::search::IsInstantExtendedAPIEnabled(browser->profile())), instant_unload_handler_(browser) { profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); profile_pref_registrar_.Add(prefs::kInstantEnabled, this); - ResetInstant(); - browser_->tab_strip_model()->AddObserver(this); + instant_.SetInstantEnabled(IsInstantEnabled(browser_->profile())); browser_->search_model()->AddObserver(this); } BrowserInstantController::~BrowserInstantController() { - browser_->tab_strip_model()->RemoveObserver(this); browser_->search_model()->RemoveObserver(this); } +bool BrowserInstantController::IsInstantEnabled(Profile* profile) { + return profile && !profile->IsOffTheRecord() && profile->GetPrefs() && + profile->GetPrefs()->GetBoolean(prefs::kInstantEnabled); +} + +void BrowserInstantController::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, false, + PrefService::SYNCABLE_PREF); + prefs->RegisterBooleanPref(prefs::kInstantEnabled, false, + PrefService::SYNCABLE_PREF); +} + bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { - // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't attempt - // to use the Instant preview. - if (!instant() || !instant_->IsCurrent() || disposition == NEW_BACKGROUND_TAB) + // Unsupported dispositions. + if (disposition == NEW_BACKGROUND_TAB || disposition == NEW_WINDOW) return false; // The omnibox currently doesn't use other dispositions, so we don't attempt @@ -70,9 +66,8 @@ bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { DCHECK(disposition == CURRENT_TAB || disposition == NEW_FOREGROUND_TAB) << disposition; - instant_->CommitCurrentPreview(disposition == CURRENT_TAB ? + return instant_.CommitIfCurrent(disposition == CURRENT_TAB ? INSTANT_COMMIT_PRESSED_ENTER : INSTANT_COMMIT_PRESSED_ALT_ENTER); - return true; } void BrowserInstantController::CommitInstant(TabContents* preview, @@ -80,7 +75,7 @@ void BrowserInstantController::CommitInstant(TabContents* preview, if (in_new_tab) { // TabStripModel takes ownership of |preview|. browser_->tab_strip_model()->AddTabContents(preview, -1, - instant_->last_transition_type(), TabStripModel::ADD_ACTIVE); + instant_.last_transition_type(), TabStripModel::ADD_ACTIVE); } else { TabContents* active_tab = browser_->tab_strip_model()->GetActiveTabContents(); @@ -113,43 +108,24 @@ gfx::Rect BrowserInstantController::GetInstantBounds() { void BrowserInstantController::InstantPreviewFocused() { // NOTE: This is only invoked on aura. browser_->window()->WebContentsFocused( - instant_->GetPreviewContents()->web_contents()); + instant_.GetPreviewContents()->web_contents()); } TabContents* BrowserInstantController::GetActiveTabContents() const { return browser_->tab_strip_model()->GetActiveTabContents(); } +void BrowserInstantController::ActiveTabChanged() { + instant_.ActiveTabChanged(); +} + //////////////////////////////////////////////////////////////////////////////// // BrowserInstantController, PrefObserver implementation: void BrowserInstantController::OnPreferenceChanged( PrefServiceBase* service, const std::string& pref_name) { - DCHECK_EQ(std::string(prefs::kInstantEnabled), pref_name); - ResetInstant(); -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserInstantController, TabStripModelObserver implementation: - -void BrowserInstantController::ActiveTabChanged( - content::WebContents* old_contents, - content::WebContents* new_contents, - int index, - bool user_gesture) { - if (instant()) { - const bool old_is_ntp = IsSearchModelNTP(old_contents); - const bool new_is_ntp = IsSearchModelNTP(new_contents); - // Do not hide Instant if switching from an NTP to another NTP since that - // would cause custom NTP content to flicker. - if (!(old_is_ntp && new_is_ntp)) - instant()->Hide(); - } -} - -void BrowserInstantController::TabStripEmpty() { - instant_.reset(); + instant_.SetInstantEnabled(IsInstantEnabled(browser_->profile())); } //////////////////////////////////////////////////////////////////////////////// @@ -157,24 +133,7 @@ void BrowserInstantController::TabStripEmpty() { void BrowserInstantController::ModeChanged(const search::Mode& old_mode, const search::Mode& new_mode) { - if (instant()) - instant_->OnActiveTabModeChanged(new_mode); -} - -//////////////////////////////////////////////////////////////////////////////// -// BrowserInstantController, private: - -void BrowserInstantController::ResetInstant() { - instant_.reset( - !browser_shutdown::ShuttingDownWithoutClosingBrowsers() && - browser_->is_type_tabbed() ? - InstantController::CreateInstant(browser_->profile(), this) : NULL); - - // Notify any observers that they need to reset. - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_BROWSER_INSTANT_RESET, - content::Source<BrowserInstantController>(this), - content::NotificationService::NoDetails()); + instant_.SearchModeChanged(old_mode, new_mode); } } // namespace chrome diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h index 90fe981..f00d8e31 100644 --- a/chrome/browser/ui/browser_instant_controller.h +++ b/chrome/browser/ui/browser_instant_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,19 +7,17 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" #include "base/prefs/public/pref_change_registrar.h" #include "base/prefs/public/pref_observer.h" -#include "base/string16.h" +#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/instant/instant_unload_handler.h" #include "chrome/browser/ui/search/search_model_observer.h" -#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" -#include "chrome/common/instant_types.h" #include "webkit/glue/window_open_disposition.h" class Browser; -class InstantController; -class InstantTest; +struct InstantSuggestion; +class PrefService; +class Profile; class TabContents; namespace gfx { @@ -28,20 +26,25 @@ class Rect; namespace chrome { -class BrowserInstantController : public TabStripModelObserver, - public search::SearchModelObserver, - public PrefObserver { +class BrowserInstantController : public PrefObserver, + public search::SearchModelObserver { public: explicit BrowserInstantController(Browser* browser); virtual ~BrowserInstantController(); + // Returns true if Instant is enabled in a visible, preview-showing mode. + static bool IsInstantEnabled(Profile* profile); + + // Registers Instant related preferences. + static void RegisterUserPrefs(PrefService* prefs); + // Commits the current Instant, returning true on success. This is intended // for use from OpenCurrentURL. bool OpenInstant(WindowOpenDisposition disposition); // Returns the InstantController or NULL if there is no InstantController for // this BrowserInstantController. - InstantController* instant() const { return instant_.get(); } + InstantController* instant() { return &instant_; } // Invoked by |instant_| to commit the |preview| by merging it into the active // tab or adding it as a new tab. We take ownership of |preview|. @@ -62,29 +65,21 @@ class BrowserInstantController : public TabStripModelObserver, // preview would be shown. TabContents* GetActiveTabContents() const; + // Invoked by |browser_| when the active tab changes. + void ActiveTabChanged(); + + private: // Overridden from PrefObserver: virtual void OnPreferenceChanged(PrefServiceBase* service, const std::string& pref_name) OVERRIDE; - // Overridden from TabStripModelObserver: - virtual void ActiveTabChanged(content::WebContents* old_contents, - content::WebContents* new_contents, - int index, - bool user_gesture) OVERRIDE; - virtual void TabStripEmpty() OVERRIDE; - // Overridden from search::SearchModelObserver: virtual void ModeChanged(const search::Mode& old_mode, const search::Mode& new_mode) OVERRIDE; - private: - // If this browser should have Instant, a new InstantController created; - // otherwise any existing InstantController is destroyed. - void ResetInstant(); - - Browser* browser_; + Browser* const browser_; - scoped_ptr<InstantController> instant_; + InstantController instant_; InstantUnloadHandler instant_unload_handler_; PrefChangeRegistrar profile_pref_registrar_; diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index c97ee42..15717f2 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,7 +12,6 @@ #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h" #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h" #include "chrome/common/content_settings_types.h" -#include "chrome/common/instant_types.h" #include "ui/gfx/native_widget_types.h" #include "webkit/glue/window_open_disposition.h" @@ -314,12 +313,12 @@ class BrowserWindow : public BaseWindow { virtual bool InPresentationMode() = 0; #endif - // Returns the desired bounds for instant in screen coordinates. Note that if - // instant isn't currently visible this returns the bounds instant would be + // Returns the desired bounds for Instant in screen coordinates. Note that if + // Instant isn't currently visible this returns the bounds Instant would be // placed at. virtual gfx::Rect GetInstantBounds() = 0; - // Checks if an instant's tab contents is being shown. + // Checks if an Instant's tab contents is being shown. virtual bool IsInstantTabShowing() = 0; // Return the correct disposition for a popup window based on |bounds|. diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index fbf74ddb..92bb2f4 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,7 +16,6 @@ #include "chrome/browser/bookmarks/bookmark_editor.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/managed_mode/managed_mode.h" #include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile.h" @@ -1886,9 +1885,9 @@ willAnimateFromState:(bookmarks::VisualState)oldState } - (void)commitInstant { - InstantController* instant = browser_->instant_controller()->instant(); - if (instant && instant->IsCurrent()) - instant->CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); + if (chrome::BrowserInstantController* controller = + browser_->instant_controller()) + controller->instant()->CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); } - (BOOL)isInstantTabShowing { diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 4030025..3f88673 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -335,7 +335,8 @@ string16 LocationBarViewMac::GetTitle() const { } InstantController* LocationBarViewMac::GetInstant() { - return browser_->instant_controller()->instant(); + return browser_->instant_controller() ? + browser_->instant_controller()->instant() : NULL; } void LocationBarViewMac::Revert() { diff --git a/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.h b/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.h index c1f14a4..69a0bb4 100644 --- a/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.h +++ b/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.h @@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_INSTANT_PREVIEW_CONTROLLER_MAC_H_ #define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_INSTANT_PREVIEW_CONTROLLER_MAC_H_ +#include "base/basictypes.h" #include "base/compiler_specific.h" -#include "chrome/browser/instant/instant_model_observer.h" #include "chrome/browser/instant/instant_preview_controller.h" class Browser; @@ -15,25 +15,19 @@ class Browser; class InstantPreviewControllerMac : public InstantPreviewController { public: - InstantPreviewControllerMac( - Browser* browser, - BrowserWindowController* window_controller, - PreviewableContentsController* previewable_contents_controller); + InstantPreviewControllerMac(Browser* browser, + BrowserWindowController* window, + PreviewableContentsController* preview); virtual ~InstantPreviewControllerMac(); - // InstantModelObserver overrides: - virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; - private: + // Overridden from InstantPreviewController: + virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; - // Weak. - BrowserWindowController* window_controller_; - - // Weak. Owns us. - PreviewableContentsController* previewable_contents_controller_; + BrowserWindowController* const window_; + PreviewableContentsController* const preview_; DISALLOW_COPY_AND_ASSIGN(InstantPreviewControllerMac); }; - #endif // CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_INSTANT_PREVIEW_CONTROLLER_MAC_H_ diff --git a/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.mm b/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.mm index ec7fa87..eb8d1b3 100644 --- a/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.mm +++ b/chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.mm @@ -11,11 +11,11 @@ InstantPreviewControllerMac::InstantPreviewControllerMac( Browser* browser, - BrowserWindowController* window_controller, - PreviewableContentsController* previewable_contents_controller) + BrowserWindowController* window, + PreviewableContentsController* preview) : InstantPreviewController(browser), - window_controller_(window_controller), - previewable_contents_controller_(previewable_contents_controller) { + window_(window), + preview_(preview) { } InstantPreviewControllerMac::~InstantPreviewControllerMac() { @@ -23,14 +23,11 @@ InstantPreviewControllerMac::~InstantPreviewControllerMac() { void InstantPreviewControllerMac::PreviewStateChanged( const InstantModel& model) { - if (model.preview_state() == InstantModel::QUERY_RESULTS) { + if (model.mode().is_search_suggestions()) { // TODO(dhollowa): Needs height and units implementation on Mac. - [previewable_contents_controller_ - showPreview:model.GetPreviewContents()->web_contents()]; + [preview_ showPreview:model.GetPreviewContents()->web_contents()]; } else { - if (![previewable_contents_controller_ isShowingPreview]) - return; - [previewable_contents_controller_ hidePreview]; + [preview_ hidePreview]; } - [window_controller_ updateBookmarkBarVisibilityWithAnimation:NO]; + [window_ updateBookmarkBarVisibilityWithAnimation:NO]; } diff --git a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h index d1b868c..1d0da58 100644 --- a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h +++ b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,8 +10,8 @@ #include "base/memory/scoped_ptr.h" class Browser; -class InstantPreviewControllerMac; @class BrowserWindowController; +class InstantPreviewControllerMac; namespace content { class WebContents; diff --git a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.mm b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.mm index dc77339..b80d159 100644 --- a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.mm +++ b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.mm @@ -1,39 +1,28 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" -#include "base/logging.h" #include "base/mac/bundle_locations.h" -#include "base/mac/mac_util.h" #include "chrome/browser/ui/cocoa/tab_contents/instant_preview_controller_mac.h" #include "content/public/browser/web_contents.h" -using content::WebContents; - @implementation PreviewableContentsController @synthesize activeContainer = activeContainer_; -// For testing. Use |-initWithBrowser:| for production. -- (id)init { - if ((self = [super initWithNibName:@"PreviewableContents" - bundle:base::mac::FrameworkBundle()])) { - } - return self; -} - - (id)initWithBrowser:(Browser*)browser windowController:(BrowserWindowController*)windowController { - if ((self = [self init])) { + if ((self = [super initWithNibName:@"PreviewableContents" + bundle:base::mac::FrameworkBundle()])) { instantPreviewController_.reset( new InstantPreviewControllerMac(browser, windowController, self)); } return self; } -- (void)showPreview:(WebContents*)preview { +- (void)showPreview:(content::WebContents*)preview { DCHECK(preview); // Remove any old preview contents before showing the new one. @@ -63,7 +52,7 @@ using content::WebContents; previewContents_ = nil; } -- (void)onActivateTabWithContents:(WebContents*)contents { +- (void)onActivateTabWithContents:(content::WebContents*)contents { if (previewContents_ == contents) { [previewContents_->GetNativeView() removeFromSuperview]; previewContents_ = nil; diff --git a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm deleted file mode 100644 index f7064db..0000000 --- a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <Cocoa/Cocoa.h> - -#import "base/memory/scoped_nsobject.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -class PreviewableContentsControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - controller_.reset([[PreviewableContentsController alloc] init]); - [[test_window() contentView] addSubview:[controller_ view]]; - } - - scoped_nsobject<PreviewableContentsController> controller_; -}; - -TEST_VIEW(PreviewableContentsControllerTest, [controller_ view]) - -// TODO(rohitrao): Test showing and hiding the preview. This may require -// changing the interface to take in a WebContentsView* instead of a -// WebContents*. - -} // namespace - diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index e10cb8f..b5b1148 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -1678,9 +1678,7 @@ void BrowserWindowGtk::InitWidgets() { TRUE, TRUE, 0); instant_preview_controller_.reset( - new InstantPreviewControllerGtk(browser_.get(), - this, - contents_container_.get())); + new InstantPreviewControllerGtk(this, contents_container_.get())); if (IsBookmarkBarSupported()) { bookmark_bar_.reset(new BookmarkBarGtk(this, diff --git a/chrome/browser/ui/gtk/instant_preview_controller_gtk.cc b/chrome/browser/ui/gtk/instant_preview_controller_gtk.cc index 05e017f..21e6a6d 100644 --- a/chrome/browser/ui/gtk/instant_preview_controller_gtk.cc +++ b/chrome/browser/ui/gtk/instant_preview_controller_gtk.cc @@ -4,15 +4,14 @@ #include "chrome/browser/ui/gtk/instant_preview_controller_gtk.h" +#include "chrome/browser/instant/instant_model.h" #include "chrome/browser/ui/gtk/browser_window_gtk.h" #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" -#include "chrome/browser/instant/instant_model.h" InstantPreviewControllerGtk::InstantPreviewControllerGtk( - Browser* browser, BrowserWindowGtk* window, TabContentsContainerGtk* contents) - : InstantPreviewController(browser), + : InstantPreviewController(window->browser()), window_(window), contents_(contents) { } @@ -22,24 +21,11 @@ InstantPreviewControllerGtk::~InstantPreviewControllerGtk() { void InstantPreviewControllerGtk::PreviewStateChanged( const InstantModel& model) { - if (model.preview_state() == InstantModel::QUERY_RESULTS) { - ShowInstant(model.GetPreviewContents(), - model.height(), model.height_units()); + if (model.mode().is_search_suggestions()) { + // TODO(jered): Support non-100% height. + contents_->SetPreview(model.GetPreviewContents()); } else { - HideInstant(); + contents_->SetPreview(NULL); } -} - -void InstantPreviewControllerGtk::ShowInstant(TabContents* preview, - int height, - InstantSizeUnits units) { - // TODO(jered): Support height < 100%. - DCHECK(height == 100 && units == INSTANT_SIZE_PERCENT); - contents_->SetPreview(preview); - window_->MaybeShowBookmarkBar(false); -} - -void InstantPreviewControllerGtk::HideInstant() { - contents_->SetPreview(NULL); window_->MaybeShowBookmarkBar(false); } diff --git a/chrome/browser/ui/gtk/instant_preview_controller_gtk.h b/chrome/browser/ui/gtk/instant_preview_controller_gtk.h index 22e64c0..f0fb71a 100644 --- a/chrome/browser/ui/gtk/instant_preview_controller_gtk.h +++ b/chrome/browser/ui/gtk/instant_preview_controller_gtk.h @@ -5,35 +5,25 @@ #ifndef CHROME_BROWSER_UI_GTK_INSTANT_PREVIEW_CONTROLLER_GTK_H_ #define CHROME_BROWSER_UI_GTK_INSTANT_PREVIEW_CONTROLLER_GTK_H_ +#include "base/basictypes.h" #include "base/compiler_specific.h" -#include "chrome/browser/instant/instant_model_observer.h" #include "chrome/browser/instant/instant_preview_controller.h" -class Browser; class BrowserWindowGtk; -class InstantModel; -class TabContents; class TabContentsContainerGtk; class InstantPreviewControllerGtk : public InstantPreviewController { public: - InstantPreviewControllerGtk(Browser* browser, - BrowserWindowGtk* window, + InstantPreviewControllerGtk(BrowserWindowGtk* window, TabContentsContainerGtk* contents); virtual ~InstantPreviewControllerGtk(); - // InstantModelObserver overrides: - virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; - private: - void ShowInstant(TabContents* preview, int height, InstantSizeUnits units); - void HideInstant(); - - // Weak. - BrowserWindowGtk* window_; + // Overridden from InstantPreviewController: + virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; - // Weak. - TabContentsContainerGtk* contents_; + BrowserWindowGtk* const window_; + TabContentsContainerGtk* const contents_; DISALLOW_COPY_AND_ASSIGN(InstantPreviewControllerGtk); }; diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc index 5417999..255e3ce 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -887,7 +887,8 @@ string16 LocationBarViewGtk::GetTitle() const { } InstantController* LocationBarViewGtk::GetInstant() { - return browser_->instant_controller()->instant(); + return browser_->instant_controller() ? + browser_->instant_controller()->instant() : NULL; } void LocationBarViewGtk::ShowFirstRunBubble() { diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc index 442cc90..beedfb8 100644 --- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc +++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -19,7 +19,6 @@ #include "chrome/browser/bookmarks/bookmark_node_data.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/defaults.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" @@ -371,7 +370,7 @@ void OmniboxViewGtk::Init() { GtkTextIter end_iter; gtk_text_buffer_get_end_iter(text_buffer_, &end_iter); - // Insert a Zero Width Space character just before the instant anchor. + // Insert a Zero Width Space character just before the Instant anchor. // It's a hack to workaround a bug of GtkTextView which can not align the // pre-edit string and a child anchor correctly when there is no other content // around the pre-edit string. @@ -743,7 +742,7 @@ int OmniboxViewGtk::TextWidth() const { GdkRectangle first_char_bounds, last_char_bounds; gtk_text_buffer_get_start_iter(text_buffer_, &start); - // Use the real end iterator here to take the width of instant suggestion + // Use the real end iterator here to take the width of Instant suggestion // text into account, so that location bar can layout its children correctly. gtk_text_buffer_get_end_iter(text_buffer_, &end); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), @@ -1446,7 +1445,7 @@ void OmniboxViewGtk::HandleInsertText(GtkTextBuffer* buffer, p = g_utf8_next_char(p)) { gunichar c = g_utf8_get_char(p); - // 0x200B is Zero Width Space, which is inserted just before the instant + // 0x200B is Zero Width Space, which is inserted just before the Instant // anchor for working around the GtkTextView's misalignment bug. // This character might be captured and inserted into the content by undo // manager, so we need to filter it out here. @@ -1459,7 +1458,7 @@ void OmniboxViewGtk::HandleInsertText(GtkTextBuffer* buffer, CollapseWhitespace(filtered_text, true)); if (!filtered_text.empty()) { - // Avoid inserting the text after the instant anchor. + // Avoid inserting the text after the Instant anchor. ValidateTextBufferIter(location); // Call the default handler to insert filtered text. @@ -1971,8 +1970,8 @@ void OmniboxViewGtk::HandleKeymapDirectionChanged(GdkKeymap* sender) { void OmniboxViewGtk::HandleDeleteRange(GtkTextBuffer* buffer, GtkTextIter* start, GtkTextIter* end) { - // Prevent the user from deleting the instant anchor. We can't simply set the - // instant anchor readonly by applying a tag with "editable" = FALSE, because + // Prevent the user from deleting the Instant anchor. We can't simply set the + // Instant anchor readonly by applying a tag with "editable" = FALSE, because // it'll prevent the insert caret from blinking. ValidateTextBufferIter(start); ValidateTextBufferIter(end); @@ -1995,7 +1994,7 @@ void OmniboxViewGtk::HandleMarkSetAlways(GtkTextBuffer* buffer, static guint signal_id = g_signal_lookup("mark-set", GTK_TYPE_TEXT_BUFFER); // "mark-set" signal is actually emitted after the mark's location is already - // set, so if the location is beyond the instant anchor, we need to move the + // set, so if the location is beyond the Instant anchor, we need to move the // mark again, which will emit the signal again. In order to prevent other // signal handlers from being called twice, we need to stop signal emission // before moving the mark again. diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h index c813ea6..6b1d60b 100644 --- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h +++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -106,7 +106,7 @@ class OmniboxViewGtk : public OmniboxView, // Sets the colors of the text view according to the theme. void SetBaseColor(); - // Sets the colors of the instant suggestion view according to the theme. + // Sets the colors of the Instant suggestion view according to the theme. void UpdateInstantViewColors(); // Returns the text view gtk widget. May return NULL if the widget @@ -309,14 +309,14 @@ class OmniboxViewGtk : public OmniboxView, GtkTextTag* security_error_scheme_tag_; GtkTextTag* normal_text_tag_; - // Objects for the instant suggestion text view. + // Objects for the Instant suggestion text view. GtkTextTag* instant_anchor_tag_; - // A widget for displaying instant suggestion text. It'll be attached to a + // A widget for displaying Instant suggestion text. It'll be attached to a // child anchor in the |text_buffer_| object. GtkWidget* instant_view_; - // A mark to split the content and the instant anchor. Wherever the end + // A mark to split the content and the Instant anchor. Wherever the end // iterator of the text buffer is required, the iterator to this mark should // be used. GtkTextMark* instant_mark_; diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc index d73ba5f..a643b74 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc +++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -234,12 +234,8 @@ bool OmniboxEditModel::CommitSuggestedText(bool skip_inline_autocomplete) { } bool OmniboxEditModel::AcceptCurrentInstantPreview() { - InstantController* instant = controller_->GetInstant(); - if (instant && instant->IsCurrent()) { - instant->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER); - return true; - } - return false; + return controller_->GetInstant() && + controller_->GetInstant()->CommitIfCurrent(INSTANT_COMMIT_PRESSED_ENTER); } void OmniboxEditModel::OnChanged() { @@ -288,7 +284,7 @@ void OmniboxEditModel::OnChanged() { // Hide any suggestions we might be showing. view_->SetInstantSuggestion(string16()); - // No need to wait any longer for instant. + // No need to wait any longer for Instant. FinalizeInstantQuery(string16(), InstantSuggestion(), false); } @@ -311,7 +307,7 @@ void OmniboxEditModel::GetDataForURLExport(GURL* url, bool OmniboxEditModel::UseVerbatimInstant() { #if defined(OS_MACOSX) // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, - // so that we can display instant suggest along with composition text. + // so that we can display Instant suggest along with composition text. const AutocompleteInput& input = autocomplete_controller_->input(); if (input.prevent_inline_autocomplete()) return true; @@ -321,11 +317,11 @@ bool OmniboxEditModel::UseVerbatimInstant() { // following conditions: // 1. If the caret is at the end of the text (checked below). // 2. If it's in IME composition mode. - // As we use a separated widget for displaying the instant suggest, it won't + // As we use a separated widget for displaying the Instant suggest, it won't // interfere with IME composition, so we don't need to care about the value of // input.prevent_inline_autocomplete() here. if (view_->DeleteAtEndPressed() || (popup_->selected_line() != 0) || - just_deleted_text_) + just_deleted_text_ || !inline_autocomplete_text_.empty()) return true; size_t start, end; @@ -624,6 +620,7 @@ void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, if (disposition != NEW_BACKGROUND_TAB) { in_revert_ = true; view_->RevertAll(); // Revert the box to its unedited state + in_revert_ = false; } if (match.type == AutocompleteMatch::EXTENSION_APP) { @@ -651,11 +648,6 @@ void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, if (match.starred) bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); - - InstantController* instant = controller_->GetInstant(); - if (instant && !popup_->IsOpen()) - instant->Hide(); - in_revert_ = false; } bool OmniboxEditModel::AcceptKeyword() { @@ -716,9 +708,8 @@ void OmniboxEditModel::OnSetFocus(bool control_down) { has_focus_ = true; control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; - InstantController* instant = controller_->GetInstant(); - if (instant) - instant->OnAutocompleteGotFocus(); + if (InstantController* instant = controller_->GetInstant()) + instant->OmniboxGotFocus(); content::WebContents* web_contents = controller_->GetWebContents(); if (web_contents) { @@ -738,7 +729,7 @@ void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { SetInstantSuggestion(InstantSuggestion()); if (InstantController* instant = controller_->GetInstant()) - instant->OnAutocompleteLostFocus(view_gaining_focus); + instant->OmniboxLostFocus(view_gaining_focus); // TODO(jered): Rip this out along with StartZeroSuggest. autocomplete_controller_->StopZeroSuggest(); @@ -769,10 +760,6 @@ bool OmniboxEditModel::OnEscapeKeyPressed() { view_->Update(NULL); } - // Let Instant decide whether to hide itself. - if (InstantController* instant = controller_->GetInstant()) - instant->OnEscapeKeyPressed(); - // If the user wasn't editing, but merely had focus in the edit, allow <esc> // to be processed as an accelerator, so it can still be used to stop a load. // When the permanent text isn't all selected we still fall through to the @@ -1005,8 +992,7 @@ bool OmniboxEditModel::OnAfterPossibleChange(const string16& old_text, } void OmniboxEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { - InstantController* instant = controller_->GetInstant(); - if (instant) + if (InstantController* instant = controller_->GetInstant()) instant->SetOmniboxBounds(bounds); } @@ -1190,39 +1176,32 @@ void OmniboxEditModel::NotifySearchTabHelper() { } bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { - if (in_revert_) + InstantController* instant = controller_->GetInstant(); + if (!instant || in_revert_) return false; - InstantController* instant = controller_->GetInstant(); + // The two pieces of text we want to send Instant, viz., what the user has + // typed, and the full omnibox text including any inline autocompletion. + string16 user_text = user_text_; + string16 full_text = user_text_ + inline_autocomplete_text_; - if (!instant) - return false; + // If there's temporary text, that overrides the user_text. In this case, we + // should ignore any inline_autocomplete_text_, because it won't be visible. + if (has_temporary_text_) + user_text = full_text = CurrentMatch().fill_into_edit; - if (user_input_in_progress_) { - // The two pieces of text we want to send Instant, viz., what the user has - // typed, and the full omnibox text including any inline autocompletion. - string16 user_text = user_text_; - string16 full_text = user_text_ + inline_autocomplete_text_; - - // If there's temporary text, that overrides the user_text. In this case, we - // should ignore any inline_autocomplete_text_, because it won't be visible. - if (has_temporary_text_) - user_text = full_text = CurrentMatch().fill_into_edit; - - // Remove keyword if we're in keyword mode. - user_text = DisplayTextFromUserText(user_text); - full_text = DisplayTextFromUserText(full_text); - - // Remove "?" if we're in forced query mode. - AutocompleteInput::RemoveForcedQueryStringIfNecessary( - autocomplete_controller_->input().type(), &user_text); - AutocompleteInput::RemoveForcedQueryStringIfNecessary( - autocomplete_controller_->input().type(), &full_text); - - return instant->Update(match, user_text, full_text, UseVerbatimInstant()); - } + // Remove keyword if we're in keyword mode. + user_text = DisplayTextFromUserText(user_text); + full_text = DisplayTextFromUserText(full_text); + + // Remove "?" if we're in forced query mode. + AutocompleteInput::RemoveForcedQueryStringIfNecessary( + autocomplete_controller_->input().type(), &user_text); + AutocompleteInput::RemoveForcedQueryStringIfNecessary( + autocomplete_controller_->input().type(), &full_text); - return false; + return instant->Update(match, user_text, full_text, UseVerbatimInstant(), + user_input_in_progress_, popup_->IsOpen()); } void OmniboxEditModel::DoPrerender(const AutocompleteMatch& match) { diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.h b/chrome/browser/ui/omnibox/omnibox_edit_model.h index c420ad4..6caf62f 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_model.h +++ b/chrome/browser/ui/omnibox/omnibox_edit_model.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,7 +12,6 @@ #include "base/time.h" #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" #include "chrome/browser/autocomplete/autocomplete_match.h" -#include "chrome/common/instant_types.h" #include "chrome/common/metrics/proto/omnibox_event.pb.h" #include "content/public/common/page_transition_types.h" #include "googleurl/src/gurl.h" @@ -21,6 +20,7 @@ class AutocompleteController; class AutocompleteResult; +struct InstantSuggestion; class OmniboxEditController; class OmniboxPopupModel; class OmniboxView; diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index ed18c6f..13996a4 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,7 +20,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/infobars/infobar_tab_helper.h" -#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/managed_mode/managed_mode.h" #include "chrome/browser/native_window_notification_source.h" #include "chrome/browser/password_manager/password_manager.h" @@ -528,7 +527,7 @@ BrowserView::~BrowserView() { launcher_item_controller_.reset(); #endif - preview_controller_.reset(NULL); + preview_controller_.reset(); browser_->tab_strip_model()->RemoveObserver(this); @@ -1510,7 +1509,7 @@ gfx::Rect BrowserView::GetInstantBounds() { } bool BrowserView::IsInstantTabShowing() { - return preview_controller_->preview_container() != NULL; + return preview_controller_->preview() != NULL; } WindowOpenDisposition BrowserView::GetDispositionForPopupBounds( @@ -1589,7 +1588,7 @@ void BrowserView::ActiveTabChanged(content::WebContents* old_contents, if (contents_->preview_web_contents() == new_contents) { contents_->MakePreviewContentsActiveContents(); views::WebView* old_container = contents_container_; - contents_container_ = preview_controller_->release_preview_container(); + contents_container_ = preview_controller_->release_preview(); old_container->SetWebContents(NULL); delete old_container; } @@ -2141,7 +2140,7 @@ void BrowserView::Init() { toolbar_->Init(); preview_controller_.reset( - new InstantPreviewControllerViews(browser(), this, contents_)); + new InstantPreviewControllerViews(browser(), contents_)); SkColor bg_color = GetWidget()->GetThemeProvider()-> GetColor(ThemeService::COLOR_TOOLBAR); diff --git a/chrome/browser/ui/views/frame/contents_container.cc b/chrome/browser/ui/views/frame/contents_container.cc index 7f9b36e..26c6700 100644 --- a/chrome/browser/ui/views/frame/contents_container.cc +++ b/chrome/browser/ui/views/frame/contents_container.cc @@ -1,21 +1,17 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/views/frame/contents_container.h" -#include "base/logging.h" #include "ui/views/controls/webview/webview.h" -using content::WebContents; - // static const char ContentsContainer::kViewClassName[] = "browser/ui/views/frame/ContentsContainer"; ContentsContainer::ContentsContainer(views::WebView* active) : active_(active), - overlay_(NULL), preview_(NULL), preview_web_contents_(NULL), active_top_margin_(0), @@ -28,25 +24,6 @@ ContentsContainer::ContentsContainer(views::WebView* active) ContentsContainer::~ContentsContainer() { } -void ContentsContainer::SetActive(views::WebView* active) { - if (active_) - RemoveChildView(active_); - active_ = active; - // Note the active view is always the first child. - if (active_) - AddChildViewAt(active_, 0); - Layout(); -} - -void ContentsContainer::SetOverlay(views::View* overlay) { - if (overlay_) - RemoveChildView(overlay_); - overlay_ = overlay; - if (overlay_) - AddChildView(overlay_); - Layout(); -} - void ContentsContainer::MakePreviewContentsActiveContents() { DCHECK(preview_); @@ -57,15 +34,13 @@ void ContentsContainer::MakePreviewContentsActiveContents() { } void ContentsContainer::SetPreview(views::WebView* preview, - WebContents* preview_web_contents, + content::WebContents* preview_web_contents, int height, InstantSizeUnits units) { - const int old_height = PreviewHeightInPixels(); - preview_height_ = height; - preview_height_units_ = units; - if (preview == preview_ && preview_web_contents_ == preview_web_contents && - old_height == PreviewHeightInPixels()) + if (preview_ == preview && preview_web_contents_ == preview_web_contents && + preview_height_ == height && preview_height_units_ == units) return; + if (preview_ != preview) { if (preview_) RemoveChildView(preview_); @@ -74,6 +49,8 @@ void ContentsContainer::SetPreview(views::WebView* preview, AddChildView(preview_); } preview_web_contents_ = preview_web_contents; + preview_height_ = height; + preview_height_units_ = units; Layout(); } @@ -87,22 +64,24 @@ void ContentsContainer::SetActiveTopMargin(int margin) { InvalidateLayout(); } -gfx::Rect ContentsContainer::GetPreviewBounds() { +gfx::Rect ContentsContainer::GetPreviewBounds() const { gfx::Point screen_loc; ConvertPointToScreen(this, &screen_loc); return gfx::Rect(screen_loc, size()); } +void ContentsContainer::SetExtraContentHeight(int height) { + if (height == extra_content_height_) + return; + extra_content_height_ = height; +} + void ContentsContainer::Layout() { int content_y = active_top_margin_; int content_height = std::max(0, height() - content_y + extra_content_height_); - if (active_) - active_->SetBounds(0, content_y, width(), content_height); - - if (overlay_) - overlay_->SetBounds(0, 0, width(), height()); + active_->SetBounds(0, content_y, width(), content_height); if (preview_) preview_->SetBounds(0, 0, width(), PreviewHeightInPixels()); @@ -112,10 +91,8 @@ void ContentsContainer::Layout() { views::View::Layout(); } -void ContentsContainer::SetExtraContentHeight(int height) { - if (height == extra_content_height_) - return; - extra_content_height_ = height; +std::string ContentsContainer::GetClassName() const { + return kViewClassName; } int ContentsContainer::PreviewHeightInPixels() const { @@ -129,7 +106,3 @@ int ContentsContainer::PreviewHeightInPixels() const { NOTREACHED() << "unknown units: " << preview_height_units_; return 0; } - -std::string ContentsContainer::GetClassName() const { - return kViewClassName; -} diff --git a/chrome/browser/ui/views/frame/contents_container.h b/chrome/browser/ui/views/frame/contents_container.h index 0216874..9f57a03 100644 --- a/chrome/browser/ui/views/frame/contents_container.h +++ b/chrome/browser/ui/views/frame/contents_container.h @@ -1,10 +1,14 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_CONTENTS_CONTAINER_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_CONTENTS_CONTAINER_H_ +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" #include "chrome/common/instant_types.h" #include "ui/views/view.h" @@ -12,13 +16,17 @@ namespace content { class WebContents; } +namespace gfx { +class Rect; +} + namespace views { class WebView; } // ContentsContainer is responsible for managing the WebContents views. // ContentsContainer has up to two children: one for the currently active -// WebContents and one for instant's WebContents. +// WebContents and one for Instant's WebContents. class ContentsContainer : public views::View { public: // Internal class name @@ -27,19 +35,8 @@ class ContentsContainer : public views::View { explicit ContentsContainer(views::WebView* active); virtual ~ContentsContainer(); - // Sets the active web view first in stacking order. This view is deactivated - // when the |SearchViewController| is displaying the NTP, and activated - // otherwise. Deactivation removes the active view from the view hierarchy. - void SetActive(views::WebView* active); - views::WebView* active() { return active_; } - - // Sets the overlay. The overlay is sized to the bounds of this view. - void SetOverlay(views::View* overlay); - views::View* overlay() { return overlay_; } - // Makes the preview view the active view and nulls out the old active view. - // It's assumed the caller will delete or remove the old active view - // separately. + // The caller must delete or remove the old active view separately. void MakePreviewContentsActiveContents(); // Sets the preview view. This does not delete the old. @@ -47,7 +44,6 @@ class ContentsContainer : public views::View { content::WebContents* preview_web_contents, int height, InstantSizeUnits units); - views::WebView* preview() { return preview_; } content::WebContents* preview_web_contents() const { return preview_web_contents_; @@ -56,13 +52,8 @@ class ContentsContainer : public views::View { // Sets the active top margin. void SetActiveTopMargin(int margin); - // Returns the bounds of the preview. If the preview isn't active this - // retuns the bounds the preview would be shown at. - gfx::Rect GetPreviewBounds(); - - // View overrides: - virtual void Layout() OVERRIDE; - virtual std::string GetClassName() const OVERRIDE; + // Returns the bounds the preview would be shown at. + gfx::Rect GetPreviewBounds() const; // Set/Get an extra content height, so that room is left at the bottom of the // contents view for other views to draw on top of the extended child web @@ -73,14 +64,17 @@ class ContentsContainer : public views::View { void SetExtraContentHeight(int height); private: - views::WebView* active_; - views::View* overlay_; - views::WebView* preview_; - content::WebContents* preview_web_contents_; + // Overridden from views::View: + virtual void Layout() OVERRIDE; + virtual std::string GetClassName() const OVERRIDE; // Returns |preview_height_| in pixels. int PreviewHeightInPixels() const; + views::WebView* active_; + views::WebView* preview_; + content::WebContents* preview_web_contents_; + // The margin between the top and the active view. This is used to make the // preview overlap the bookmark bar on the new tab page. int active_top_margin_; diff --git a/chrome/browser/ui/views/frame/instant_preview_controller_views.cc b/chrome/browser/ui/views/frame/instant_preview_controller_views.cc index 4a67e2b..fd6c76d 100644 --- a/chrome/browser/ui/views/frame/instant_preview_controller_views.cc +++ b/chrome/browser/ui/views/frame/instant_preview_controller_views.cc @@ -4,22 +4,19 @@ #include "chrome/browser/ui/views/frame/instant_preview_controller_views.h" +#include "chrome/browser/instant/instant_model.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/contents_container.h" -#include "chrome/browser/instant/instant_model.h" #include "ui/views/controls/webview/webview.h" InstantPreviewControllerViews::InstantPreviewControllerViews( Browser* browser, - BrowserView* browser_view, ContentsContainer* contents) : InstantPreviewController(browser), - browser_view_(browser_view), - contents_(contents), - preview_container_(NULL) { + contents_(contents) { } InstantPreviewControllerViews::~InstantPreviewControllerViews() { @@ -27,35 +24,21 @@ InstantPreviewControllerViews::~InstantPreviewControllerViews() { void InstantPreviewControllerViews::PreviewStateChanged( const InstantModel& model) { - if (model.preview_state() == InstantModel::QUERY_RESULTS || - model.preview_state() == InstantModel::CUSTOM_NTP_CONTENT) { - ShowInstant(model.GetPreviewContents(), - model.height(), model.height_units()); - } else { - HideInstant(); - } -} - -void InstantPreviewControllerViews::ShowInstant(TabContents* preview, - int height, - InstantSizeUnits units) { - if (!preview_container_) { - preview_container_ = new views::WebView(browser_->profile()); - preview_container_->set_id(VIEW_ID_TAB_CONTAINER); + if (model.mode().is_ntp() || model.mode().is_search_suggestions()) { + // Show the preview. + if (!preview_) { + preview_.reset(new views::WebView(browser_->profile())); + preview_->set_id(VIEW_ID_TAB_CONTAINER); + } + content::WebContents* web_contents = + model.GetPreviewContents()->web_contents(); + contents_->SetPreview(preview_.get(), web_contents, + model.height(), model.height_units()); + preview_->SetWebContents(web_contents); + } else if (preview_) { + // Hide the preview. SetWebContents() must happen before SetPreview(). + preview_->SetWebContents(NULL); + contents_->SetPreview(NULL, NULL, 100, INSTANT_SIZE_PERCENT); + preview_.reset(); } - contents_->SetPreview(preview_container_, - preview->web_contents(), - height, units); - preview_container_->SetWebContents(preview->web_contents()); -} - -void InstantPreviewControllerViews::HideInstant() { - if (!preview_container_) - return; - - // The contents must be changed before SetPreview is invoked. - preview_container_->SetWebContents(NULL); - contents_->SetPreview(NULL, NULL, 100, INSTANT_SIZE_PERCENT); - delete preview_container_; - preview_container_ = NULL; } diff --git a/chrome/browser/ui/views/frame/instant_preview_controller_views.h b/chrome/browser/ui/views/frame/instant_preview_controller_views.h index b241612..d80e5f2 100644 --- a/chrome/browser/ui/views/frame/instant_preview_controller_views.h +++ b/chrome/browser/ui/views/frame/instant_preview_controller_views.h @@ -5,53 +5,40 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_INSTANT_PREVIEW_CONTROLLER_VIEWS_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_INSTANT_PREVIEW_CONTROLLER_VIEWS_H_ +#include "base/basictypes.h" #include "base/compiler_specific.h" -#include "chrome/browser/instant/instant_model_observer.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/instant/instant_preview_controller.h" class Browser; -class BrowserView; class ContentsContainer; -class InstantModel; -class TabContents; namespace views { class WebView; } -// A controller that manages the Views-specific Instant preview. Its primary +// A controller that manages the Views-specific Instant preview. Its primary // role is to respond to display-state changes from the Instant model and // reflect this in the visibility and layout of the preview. class InstantPreviewControllerViews : public InstantPreviewController { public: - InstantPreviewControllerViews(Browser* browser, - BrowserView* browser_view, - ContentsContainer* contents); + InstantPreviewControllerViews(Browser* browser, ContentsContainer* contents); virtual ~InstantPreviewControllerViews(); - // InstantModelObserver overrides: - virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; + views::WebView* preview() { return preview_.get(); } - views::WebView* preview_container() { return preview_container_; } - views::WebView* release_preview_container() { - views::WebView* tmp = preview_container_; - preview_container_ = NULL; - return tmp; + views::WebView* release_preview() WARN_UNUSED_RESULT { + return preview_.release(); } private: - void ShowInstant(TabContents* preview, int height, InstantSizeUnits units); - void HideInstant(); - - // Weak. - BrowserView* browser_view_; + // Overridden from InstantPreviewController: + virtual void PreviewStateChanged(const InstantModel& model) OVERRIDE; - // Weak. - ContentsContainer* contents_; + ContentsContainer* const contents_; // The view that contains the Instant preview web contents. - // Lazily created in ShowInstant() with ownership passed to |contents_|. - views::WebView* preview_container_; + scoped_ptr<views::WebView> preview_; DISALLOW_COPY_AND_ASSIGN(InstantPreviewControllerViews); }; diff --git a/chrome/browser/ui/views/toolbar_view.cc b/chrome/browser/ui/views/toolbar_view.cc index 9a794cf..2714606 100644 --- a/chrome/browser/ui/views/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -454,7 +454,8 @@ WebContents* ToolbarView::GetWebContents() const { } InstantController* ToolbarView::GetInstant() { - return browser_->instant_controller()->instant(); + return browser_->instant_controller() ? + browser_->instant_controller()->instant() : NULL; } ContentSettingBubbleModelDelegate* diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index a164a9d..54e8439 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -1,5 +1,4 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# +# Copyright 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -2468,7 +2467,6 @@ 'browser/ui/browser.cc', 'browser/ui/browser_command_controller.cc', 'browser/ui/browser_finder.cc', - 'browser/ui/browser_instant_controller.cc', 'browser/ui/browser_list.cc', 'browser/ui/browser_navigator.cc', 'browser/ui/browser_otr_state.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 54e0e65..bcf375b 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Copyright 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. { @@ -1304,7 +1304,6 @@ 'browser/ui/cocoa/styled_text_field_test_helper.h', 'browser/ui/cocoa/styled_text_field_test_helper.mm', 'browser/ui/cocoa/styled_text_field_unittest.mm', - 'browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm', 'browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm', 'browser/ui/cocoa/tab_contents/sad_tab_view_unittest.mm', 'browser/ui/cocoa/tab_view_picker_table_unittest.mm', diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h index 90e8f18..28d412f 100644 --- a/chrome/common/chrome_notification_types.h +++ b/chrome/common/chrome_notification_types.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -1112,10 +1112,6 @@ enum NotificationType { // Instant API or not. NOTIFICATION_INSTANT_SUPPORT_DETERMINED, - // Sent when the Browser Instant controller resets, this may result from - // a preference change. - NOTIFICATION_BROWSER_INSTANT_RESET, - // Sent when the CaptivePortalService checks if we're behind a captive portal. // The Source is the Profile the CaptivePortalService belongs to, and the // Details are a Details<CaptivePortalService::CheckResults>. diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h index d2d752a..43ea959 100644 --- a/chrome/renderer/searchbox/searchbox.h +++ b/chrome/renderer/searchbox/searchbox.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,10 +18,6 @@ namespace content { class RenderView; } -namespace IPC { -class Message; -} - class SearchBox : public content::RenderViewObserver, public content::RenderViewObserverTracker<SearchBox> { public: @@ -50,7 +46,7 @@ class SearchBox : public content::RenderViewObserver, GetAutocompleteResultWithId(size_t restricted_id) const; private: - // RenderViewObserver implementation. + // Overridden from content::RenderViewObserver: virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; void OnChange(const string16& query, diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index c2aa810..3482ab6 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc @@ -1,11 +1,10 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/renderer/searchbox/searchbox_extension.h" #include "base/stringprintf.h" -#include "base/utf_string_conversions.h" #include "chrome/renderer/searchbox/searchbox.h" #include "content/public/renderer/render_view.h" #include "grit/renderer_resources.h" @@ -256,6 +255,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetQuery( content::RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); + DVLOG(1) << "GetQuery: '" << SearchBox::Get(render_view)->query() << "'"; return UTF16ToV8String(SearchBox::Get(render_view)->query()); } @@ -265,6 +265,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetVerbatim( content::RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); + DVLOG(1) << "GetVerbatim: " << SearchBox::Get(render_view)->verbatim(); return v8::Boolean::New(SearchBox::Get(render_view)->verbatim()); } @@ -325,6 +326,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( const v8::Arguments& args) { + DVLOG(1) << "GetAutocompleteResults"; content::RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); @@ -360,6 +362,8 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetContext( content::RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); + DVLOG(1) << "GetContext: isNewTabPage=" + << SearchBox::Get(render_view)->active_tab_is_ntp(); v8::Handle<v8::Object> context = v8::Object::New(); context->Set( v8::String::New("isNewTabPage"), @@ -395,6 +399,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateContentWindow( // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( const v8::Arguments& args) { + DVLOG(1) << "SetSuggestions"; content::RenderView* render_view = GetRenderView(); if (!render_view || !args.Length()) return v8::Undefined(); @@ -433,6 +438,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuerySuggestion( const v8::Arguments& args) { + DVLOG(1) << "SetQuerySuggestion"; content::RenderView* render_view = GetRenderView(); if (!render_view || args.Length() < 2) return v8::Undefined(); @@ -456,6 +462,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuerySuggestion( v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuerySuggestionFromAutocompleteResult( const v8::Arguments& args) { + DVLOG(1) << "SetQuerySuggestionFromAutocompleteResult"; content::RenderView* render_view = GetRenderView(); if (!render_view || !args.Length()) return v8::Undefined(); @@ -478,6 +485,7 @@ v8::Handle<v8::Value> // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuery( const v8::Arguments& args) { + DVLOG(1) << "SetQuery"; content::RenderView* render_view = GetRenderView(); if (!render_view || args.Length() < 2) return v8::Undefined(); @@ -498,6 +506,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQuery( v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( const v8::Arguments& args) { + DVLOG(1) << "SetQueryFromAutocompleteResult"; content::RenderView* render_view = GetRenderView(); if (!render_view || !args.Length()) return v8::Undefined(); @@ -522,12 +531,12 @@ v8::Handle<v8::Value> // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::Show( const v8::Arguments& args) { + DVLOG(1) << "ShowInstantPreview"; content::RenderView* render_view = GetRenderView(); if (!render_view || args.Length() < 2) return v8::Undefined(); InstantShownReason reason = INSTANT_SHOWN_NOT_SPECIFIED; switch (args[0]->Uint32Value()) { - case 0: reason = INSTANT_SHOWN_NOT_SPECIFIED; break; case 1: reason = INSTANT_SHOWN_CUSTOM_NTP_CONTENT; break; case 2: reason = INSTANT_SHOWN_QUERY_SUGGESTIONS; break; case 3: reason = INSTANT_SHOWN_ZERO_SUGGESTIONS; break; @@ -547,6 +556,7 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::Show( // static void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) { + DVLOG(1) << "DispatchChange"; Dispatch(frame, kDispatchChangeEventScript); } @@ -579,11 +589,13 @@ bool SearchBoxExtension::PageSupportsInstant(WebKit::WebFrame* frame) { if (supports_instant) DispatchResize(frame); + DVLOG(1) << "PageSupportsInstant: " << supports_instant; return supports_instant; } // static void SearchBoxExtension::DispatchAutocompleteResults(WebKit::WebFrame* frame) { + DVLOG(1) << "DispatchAutocompleteResults"; Dispatch(frame, kDispatchAutocompleteResultsEventScript); } @@ -597,6 +609,7 @@ void SearchBoxExtension::DispatchUpOrDownKeyPress(WebKit::WebFrame* frame, // static void SearchBoxExtension::DispatchContextChange(WebKit::WebFrame* frame) { + DVLOG(1) << "DispatchContextChange"; Dispatch(frame, kDispatchContextChangeEventScript); } |