summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-21 07:27:47 +0000
committeroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-21 07:27:47 +0000
commit37177e0e2e5a6fa7b67976f757279adf6c36f5ca (patch)
treebcd0066865992e0de6d590cfc67bbab72e8f2094 /chrome
parent2e5912800b9d4ba8472085e200322abb43fa3339 (diff)
downloadchromium_src-37177e0e2e5a6fa7b67976f757279adf6c36f5ca.zip
chromium_src-37177e0e2e5a6fa7b67976f757279adf6c36f5ca.tar.gz
chromium_src-37177e0e2e5a6fa7b67976f757279adf6c36f5ca.tar.bz2
Views-implementation of AutocompleteEditView.
This is based on GTK implementation. Please see the header file for features that are not implemented yet. Textfield changes (files under views/controls/textfield) are being reviewed by Ben in separate CL (http://codereview.chromium.org/6314012/), so you don't have to review them (but you're welcome to do so). * Updated factory method in AutocompleteEditViewGtk to return views-implementation when TextfieldViews is enabled. * Added new option to FillLayout so that it lays out its child inside border. * Added missing GD_PK_Delete to keycode conversion. * Enabled tests in autodomplete_edit_view_browsertests for views-implementation as well. I moved the test body to the class and then called them from each test class to avoid having another test configuration on bots. Let me know if there is better way. BUG=none TEST=Enabled autocomplete_edit_view_browsertest for views-implementation. Review URL: http://codereview.chromium.org/6245003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72113 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc844
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc14
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_views.cc635
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_views.h207
-rw-r--r--chrome/chrome_browser.gypi2
5 files changed, 1333 insertions, 369 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc
index 247ef03..5ecd047 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc
@@ -38,6 +38,10 @@
#include <gtk/gtk.h>
#endif
+#if defined(TOOLKIT_VIEWS)
+#include "views/controls/textfield/native_textfield_views.h"
+#endif
+
using base::Time;
using base::TimeDelta;
@@ -140,7 +144,12 @@ class AutocompleteEditViewTest : public InProcessBrowserTest,
ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
ASSERT_NO_FATAL_FAILURE(SetupComponents());
browser()->FocusLocationBar();
- ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR));
+#if defined(TOOLKIT_VIEWS)
+ if (views::NativeTextfieldViews::IsTextfieldViewsEnabled())
+ return;
+#endif
+ ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
+ VIEW_ID_LOCATION_BAR));
}
static void GetAutocompleteEditViewForBrowser(
@@ -268,8 +277,8 @@ class AutocompleteEditViewTest : public InProcessBrowserTest,
ui_test_utils::RunMessageLoop();
}
- // Add enough history pages containing |kSearchText| to trigger open history
- // page url in autocomplete result.
+ // Add enough history pages containing |kSearchText| to trigger
+ // open history page url in autocomplete result.
for (size_t i = 0; i < arraysize(kHistoryEntries); i++) {
const TestHistoryEntry& cur = kHistoryEntries[i];
GURL url(cur.url);
@@ -314,449 +323,499 @@ class AutocompleteEditViewTest : public InProcessBrowserTest,
}
MessageLoopForUI::current()->Quit();
}
-};
-// Test if ctrl-* accelerators are workable in omnibox.
-// See http://crbug.com/19193: omnibox blocks ctrl-* commands
-//
-// Flaky on interactive tests (dbg), http://crbug.com/69433
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, FLAKY_BrowserAccelerators) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ void BrowserAcceleratorsTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- int tab_count = browser()->tab_count();
+ int tab_count = browser()->tab_count();
- // Create a new Tab.
- browser()->NewTab();
- ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
+ // Create a new Tab.
+ browser()->NewTab();
+ ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
- // Select the first Tab.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, true, false, false));
- ASSERT_EQ(0, browser()->selected_index());
+ // Select the first Tab.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, true, false, false));
+ ASSERT_EQ(0, browser()->selected_index());
- browser()->FocusLocationBar();
+ browser()->FocusLocationBar();
- // Select the second Tab.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, true, false, false));
- ASSERT_EQ(1, browser()->selected_index());
+ // Select the second Tab.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, true, false, false));
+ ASSERT_EQ(1, browser()->selected_index());
- browser()->FocusLocationBar();
+ browser()->FocusLocationBar();
- // Try ctrl-w to close a Tab.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, true, false, false));
- ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count));
+ // Try ctrl-w to close a Tab.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, true, false, false));
+ ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count));
- // Try ctrl-l to focus location bar.
- edit_view->SetUserText(L"Hello world");
- EXPECT_FALSE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, true, false, false));
- EXPECT_TRUE(edit_view->IsSelectAll());
+ // Try ctrl-l to focus location bar.
+ edit_view->SetUserText(L"Hello world");
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, true, false, false));
+ EXPECT_TRUE(edit_view->IsSelectAll());
- // Try editing the location bar text.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, false, false, false));
- EXPECT_FALSE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, false, false, false));
- EXPECT_EQ(L"Hello worlds", edit_view->GetText());
+ // Try editing the location bar text.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, false, false, false));
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, false, false, false));
+ EXPECT_EQ(L"Hello worlds", edit_view->GetText());
- // Try ctrl-x to cut text.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, true, true, false));
- EXPECT_FALSE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, true, false, false));
- EXPECT_EQ(L"Hello ", edit_view->GetText());
+ // Try ctrl-x to cut text.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, true, true, false));
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, true, false, false));
+ EXPECT_EQ(L"Hello ", edit_view->GetText());
#if !defined(OS_CHROMEOS)
- // Try alt-f4 to close the browser.
- ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
- browser(), ui::VKEY_F4, false, false, true, false,
- NotificationType::BROWSER_CLOSED, Source<Browser>(browser())));
+ // Try alt-f4 to close the browser.
+ ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+ browser(), ui::VKEY_F4, false, false, true, false,
+ NotificationType::BROWSER_CLOSED, Source<Browser>(browser())));
#endif
-}
+ }
-// Flakily fails and times out on Win only. http://crbug.com/69941
-#if defined(OS_WIN)
-#define MAYBE_PopupAccelerators DISABLED_PopupAccelerators
-#else
-#define MAYBE_PopupAccelerators PopupAccelerators
+ void PopupAcceleratorsTest() {
+ // Create a popup.
+ Browser* popup = CreateBrowserForPopup(browser()->profile());
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(
+ GetAutocompleteEditViewForBrowser(popup, &edit_view));
+ popup->FocusLocationBar();
+ EXPECT_TRUE(edit_view->IsSelectAll());
+
+ // Try ctrl-w to close the popup.
+ ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+ popup, ui::VKEY_W, true, false, false, false,
+ NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
+
+ // Create another popup.
+ popup = CreateBrowserForPopup(browser()->profile());
+ ASSERT_NO_FATAL_FAILURE(
+ GetAutocompleteEditViewForBrowser(popup, &edit_view));
+
+ // Set the edit text to "Hello world".
+ edit_view->SetUserText(L"Hello world");
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ popup->FocusLocationBar();
+ EXPECT_TRUE(edit_view->IsSelectAll());
+
+ // Try editing the location bar text -- should be disallowed.
+ ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_RIGHT, false,
+ false, false));
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, false, false,
+ false));
+ EXPECT_EQ(L"Hello world", edit_view->GetText());
+
+ // Try ctrl-x to cut text -- should be disallowed.
+ ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_LEFT, true, true,
+ false));
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_X, true, false,
+ false));
+ EXPECT_EQ(L"Hello world", edit_view->GetText());
+
+#if !defined(OS_CHROMEOS)
+ // Try alt-f4 to close the popup.
+ ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+ popup, ui::VKEY_F4, false, false, true, false,
+ NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
#endif
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, MAYBE_PopupAccelerators) {
- // Create a popup.
- Browser* popup = CreateBrowserForPopup(browser()->profile());
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditViewForBrowser(popup, &edit_view));
- popup->FocusLocationBar();
- EXPECT_TRUE(edit_view->IsSelectAll());
+ }
- // Try ctrl-w to close the popup.
- ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
- popup, ui::VKEY_W, true, false, false, false,
- NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
+ void BackspaceInKeywordModeTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- // Create another popup.
- popup = CreateBrowserForPopup(browser()->profile());
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditViewForBrowser(popup, &edit_view));
+ // Trigger keyword hint mode.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
- // Set the edit text to "Hello world".
- edit_view->SetUserText(L"Hello world");
- EXPECT_FALSE(edit_view->IsSelectAll());
- popup->FocusLocationBar();
- EXPECT_TRUE(edit_view->IsSelectAll());
+ // Trigger keyword mode.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, false, false, false));
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
- // Try editing the location bar text -- should be disallowed.
- ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_RIGHT, false,
- false, false));
- EXPECT_FALSE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, false, false,
- false));
- EXPECT_EQ(L"Hello world", edit_view->GetText());
+ // Backspace without search text should bring back keyword hint mode.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
- // Try ctrl-x to cut text -- should be disallowed.
- ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_LEFT, true, true,
- false));
- EXPECT_FALSE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_X, true, false,
- false));
- EXPECT_EQ(L"Hello world", edit_view->GetText());
+ // Trigger keyword mode again.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, false, false, false));
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
-#if !defined(OS_CHROMEOS)
- // Try alt-f4 to close the popup.
- ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
- popup, ui::VKEY_F4, false, false, true, false,
- NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
-#endif
-}
+ // Input something as search text.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BackspaceInKeywordMode) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ // Should stay in keyword mode while deleting search text by pressing
+ // backspace.
+ for (size_t i = 0; i < arraysize(kSearchText) - 1; ++i) {
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
+ }
- // Trigger keyword hint mode.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
+ // Input something as search text.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
- // Trigger keyword mode.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, false, false, false));
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
+ // Move cursor to the beginning of the search text.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, false, false, false));
+ // Backspace at the beginning of the search text shall turn off
+ // the keyword mode.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(std::string(), WideToUTF8(edit_view->model()->keyword()));
+ ASSERT_EQ(std::string(kSearchKeyword) + kSearchText,
+ WideToUTF8(edit_view->GetText()));
+ }
- // Backspace without search text should bring back keyword hint mode.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
+ void EscapeTest() {
+ ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
+ browser()->FocusLocationBar();
- // Trigger keyword mode again.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, false, false, false));
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- // Input something as search text.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
+ std::wstring old_text = edit_view->GetText();
+ EXPECT_FALSE(old_text.empty());
+ EXPECT_TRUE(edit_view->IsSelectAll());
- // Should stay in keyword mode while deleting search text by pressing
- // backspace.
- for (size_t i = 0; i < arraysize(kSearchText) - 1; ++i) {
+ // Delete all text in omnibox.
ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(kSearchKeyword, WideToUTF8(edit_view->model()->keyword()));
- }
+ EXPECT_TRUE(edit_view->GetText().empty());
- // Input something as search text.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
+ // Escape shall revert the text in omnibox.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, false, false, false));
+ EXPECT_EQ(old_text, edit_view->GetText());
+ EXPECT_TRUE(edit_view->IsSelectAll());
+ }
- // Move cursor to the beginning of the search text.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, false, false, false));
- // Backspace at the beginning of the search text shall turn off
- // the keyword mode.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(std::string(), WideToUTF8(edit_view->model()->keyword()));
- ASSERT_EQ(std::string(kSearchKeyword) + kSearchText,
- WideToUTF8(edit_view->GetText()));
-}
+ void DesiredTLDTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
+ ASSERT_TRUE(popup_model);
+
+ // Test ctrl-Enter.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kDesiredTLDKeys));
+ ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
+ ASSERT_TRUE(popup_model->IsOpen());
+ // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be opened.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, true, false, false));
+
+ GURL url = browser()->GetSelectedTabContents()->GetURL();
+ EXPECT_STREQ(kDesiredTLDHostname, url.host().c_str());
+ }
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, Escape) {
- ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
- browser()->FocusLocationBar();
+ void AltEnterTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ edit_view->SetUserText(ASCIIToWide(chrome::kChromeUIHistoryURL));
+ int tab_count = browser()->tab_count();
+ // alt-Enter opens a new tab.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, true));
+ ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
+ }
- std::wstring old_text = edit_view->GetText();
- EXPECT_FALSE(old_text.empty());
- EXPECT_TRUE(edit_view->IsSelectAll());
+ void EnterToSearchTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
+ ASSERT_TRUE(popup_model);
- // Delete all text in omnibox.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- EXPECT_TRUE(edit_view->GetText().empty());
+ // Test Enter to search.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
+ ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
+ ASSERT_TRUE(popup_model->IsOpen());
- // Escape shall revert the text in omnibox.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, false, false, false));
- EXPECT_EQ(old_text, edit_view->GetText());
- EXPECT_TRUE(edit_view->IsSelectAll());
-}
+ // Check if the default match result is Search Primary Provider.
+ ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
+ popup_model->result().default_match()->type);
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DesiredTLD) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
- ASSERT_TRUE(popup_model);
+ // Open the default match.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, false));
+ GURL url = browser()->GetSelectedTabContents()->GetURL();
+ EXPECT_STREQ(kSearchTextURL, url.spec().c_str());
- // Test ctrl-Enter.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kDesiredTLDKeys));
- ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
- ASSERT_TRUE(popup_model->IsOpen());
- // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be opened.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, true, false, false));
+ // Test that entering a single character then Enter performs a search.
+ browser()->FocusLocationBar();
+ EXPECT_TRUE(edit_view->IsSelectAll());
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys));
+ ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
+ ASSERT_TRUE(popup_model->IsOpen());
+ EXPECT_EQ(kSearchSingleChar, WideToUTF8(edit_view->GetText()));
+
+ // Check if the default match result is Search Primary Provider.
+ ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
+ popup_model->result().default_match()->type);
+
+ // Open the default match.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, false));
+ url = browser()->GetSelectedTabContents()->GetURL();
+ EXPECT_STREQ(kSearchSingleCharURL, url.spec().c_str());
+ }
- GURL url = browser()->GetSelectedTabContents()->GetURL();
- EXPECT_STREQ(kDesiredTLDHostname, url.host().c_str());
-}
+ void EscapeToDefaultMatchTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
+ ASSERT_TRUE(popup_model);
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AltEnter) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ // Input something to trigger inline autocomplete.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
+ ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
+ ASSERT_TRUE(popup_model->IsOpen());
- edit_view->SetUserText(ASCIIToWide(chrome::kChromeUIHistoryURL));
- int tab_count = browser()->tab_count();
- // alt-Enter opens a new tab.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, true));
- ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
-}
+ std::wstring old_text = edit_view->GetText();
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EnterToSearch) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
- ASSERT_TRUE(popup_model);
+ // Make sure inline autocomplete is triggerred.
+ EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
- // Test Enter to search.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
- ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
- ASSERT_TRUE(popup_model->IsOpen());
+ size_t old_selected_line = popup_model->selected_line();
+ EXPECT_EQ(0U, old_selected_line);
- // Check if the default match result is Search Primary Provider.
- ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
- popup_model->result().default_match()->type);
+ // Move to another line with different text.
+ size_t size = popup_model->result().size();
+ while (popup_model->selected_line() < size - 1) {
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, false, false, false));
+ ASSERT_NE(old_selected_line, popup_model->selected_line());
+ if (old_text != edit_view->GetText())
+ break;
+ }
- // Open the default match.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, false));
- GURL url = browser()->GetSelectedTabContents()->GetURL();
- EXPECT_STREQ(kSearchTextURL, url.spec().c_str());
+ EXPECT_NE(old_text, edit_view->GetText());
- // Test that entering a single character then Enter performs a search.
- browser()->FocusLocationBar();
- EXPECT_TRUE(edit_view->IsSelectAll());
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys));
- ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
- ASSERT_TRUE(popup_model->IsOpen());
- EXPECT_EQ(kSearchSingleChar, WideToUTF8(edit_view->GetText()));
+ // Escape shall revert back to the default match item.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, false, false, false));
+ EXPECT_EQ(old_text, edit_view->GetText());
+ EXPECT_EQ(old_selected_line, popup_model->selected_line());
+ }
- // Check if the default match result is Search Primary Provider.
- ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
- popup_model->result().default_match()->type);
+ void BasicTextOperationsTest() {
+ ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
+ browser()->FocusLocationBar();
- // Open the default match.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, false, false, false));
- url = browser()->GetSelectedTabContents()->GetURL();
- EXPECT_STREQ(kSearchSingleCharURL, url.spec().c_str());
-}
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EscapeToDefaultMatch) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
- ASSERT_TRUE(popup_model);
+ std::wstring old_text = edit_view->GetText();
+ EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL), old_text);
+ EXPECT_TRUE(edit_view->IsSelectAll());
- // Input something to trigger inline autocomplete.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
- ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
- ASSERT_TRUE(popup_model->IsOpen());
+ std::wstring::size_type start, end;
+ edit_view->GetSelectionBounds(&start, &end);
+ EXPECT_EQ(0U, start);
+ EXPECT_EQ(old_text.size(), end);
- std::wstring old_text = edit_view->GetText();
+ // Move the cursor to the end.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, false, false, false));
+ EXPECT_FALSE(edit_view->IsSelectAll());
- // Make sure inline autocomplete is triggerred.
- EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
+ // Make sure the cursor is placed correctly.
+ edit_view->GetSelectionBounds(&start, &end);
+ EXPECT_EQ(old_text.size(), start);
+ EXPECT_EQ(old_text.size(), end);
- size_t old_selected_line = popup_model->selected_line();
- EXPECT_EQ(0U, old_selected_line);
+ // Insert one character at the end. Make sure we won't insert
+ // anything after the special ZWS mark used in gtk implementation.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, false, false, false));
+ EXPECT_EQ(old_text + L"a", edit_view->GetText());
- // Move to another line with different text.
- size_t size = popup_model->result().size();
- while (popup_model->selected_line() < size - 1) {
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, false, false, false));
- ASSERT_NE(old_selected_line, popup_model->selected_line());
- if (old_text != edit_view->GetText())
- break;
+ // Delete one character from the end. Make sure we won't delete the special
+ // ZWS mark used in gtk implementation.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
+ EXPECT_EQ(old_text, edit_view->GetText());
+
+ edit_view->SelectAll(true);
+ EXPECT_TRUE(edit_view->IsSelectAll());
+ edit_view->GetSelectionBounds(&start, &end);
+ EXPECT_EQ(0U, start);
+ EXPECT_EQ(old_text.size(), end);
+
+ // Delete the content
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, false, false, false));
+ EXPECT_TRUE(edit_view->IsSelectAll());
+ edit_view->GetSelectionBounds(&start, &end);
+ EXPECT_EQ(0U, start);
+ EXPECT_EQ(0U, end);
+ EXPECT_TRUE(edit_view->GetText().empty());
+
+ // Check if RevertAll() can set text and cursor correctly.
+ edit_view->RevertAll();
+ EXPECT_FALSE(edit_view->IsSelectAll());
+ EXPECT_EQ(old_text, edit_view->GetText());
+ edit_view->GetSelectionBounds(&start, &end);
+ EXPECT_EQ(old_text.size(), start);
+ EXPECT_EQ(old_text.size(), end);
}
- EXPECT_NE(old_text, edit_view->GetText());
+ void AcceptKeywordBySpaceTest() {
+ AutocompleteEditView* edit_view = NULL;
+ ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
- // Escape shall revert back to the default match item.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, false, false, false));
- EXPECT_EQ(old_text, edit_view->GetText());
- EXPECT_EQ(old_selected_line, popup_model->selected_line());
-}
+ std::wstring text = UTF8ToWide(kSearchKeyword);
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BasicTextOperations) {
- ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
- browser()->FocusLocationBar();
+ // Trigger keyword hint mode.
+ ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text, edit_view->GetText());
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+ // Trigger keyword mode by space.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_TRUE(edit_view->GetText().empty());
+
+ // Revert to keyword hint mode.
+ edit_view->model()->ClearKeyword(std::wstring());
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text, edit_view->GetText());
+
+ // Keyword should also be accepted by typing an ideographic space.
+ edit_view->OnBeforePossibleChange();
+ edit_view->SetWindowTextAndCaretPos(text + L"\x3000", text.length() + 1);
+ edit_view->OnAfterPossibleChange();
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_TRUE(edit_view->GetText().empty());
+
+ // Revert to keyword hint mode.
+ edit_view->model()->ClearKeyword(std::wstring());
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text, edit_view->GetText());
+
+ // Keyword shouldn't be accepted by pasting.
+ // Simulate pasting a whitespace to the end of content.
+ edit_view->OnBeforePossibleChange();
+ edit_view->model()->on_paste();
+ edit_view->SetWindowTextAndCaretPos(text + L" ", text.length() + 1);
+ edit_view->OnAfterPossibleChange();
+ // Should be still in keyword hint mode.
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ // Keyword shouldn't be accepted by pressing space with a trailing
+ // whitespace.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ // Keyword shouldn't be accepted by deleting the trailing space.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ // Keyword shouldn't be accepted by pressing space in the middle
+ // of content.
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, false, false, false));
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ // Keyword shouldn't be accepted by pasting "foo bar".
+ edit_view->SetUserText(std::wstring());
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_TRUE(edit_view->model()->keyword().empty());
- std::wstring old_text = edit_view->GetText();
- EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL), old_text);
- EXPECT_TRUE(edit_view->IsSelectAll());
+ edit_view->OnBeforePossibleChange();
+ edit_view->model()->on_paste();
+ edit_view->SetWindowTextAndCaretPos(text + L" bar", text.length() + 4);
+ edit_view->OnAfterPossibleChange();
+ ASSERT_FALSE(edit_view->model()->is_keyword_hint());
+ ASSERT_TRUE(edit_view->model()->keyword().empty());
+ ASSERT_EQ(text + L" bar", edit_view->GetText());
+
+ // Keyword shouldn't be accepted by pressing space with a selected range.
+ edit_view->OnBeforePossibleChange();
+ edit_view->OnInlineAutocompleteTextMaybeChanged(
+ text + L" ", text.length());
+ edit_view->OnAfterPossibleChange();
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ std::wstring::size_type start, end;
+ edit_view->GetSelectionBounds(&start, &end);
+ ASSERT_NE(start, end);
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
+ ASSERT_TRUE(edit_view->model()->is_keyword_hint());
+ ASSERT_EQ(text, edit_view->model()->keyword());
+ ASSERT_EQ(text + L" ", edit_view->GetText());
+
+ edit_view->GetSelectionBounds(&start, &end);
+ ASSERT_EQ(start, end);
+ }
- std::wstring::size_type start, end;
- edit_view->GetSelectionBounds(&start, &end);
- EXPECT_EQ(0U, start);
- EXPECT_EQ(old_text.size(), end);
+};
- // Move the cursor to the end.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, false, false, false));
- EXPECT_FALSE(edit_view->IsSelectAll());
+// Test if ctrl-* accelerators are workable in omnibox.
+// See http://crbug.com/19193: omnibox blocks ctrl-* commands
+//
+// Flaky on interactive tests (dbg), http://crbug.com/69433
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, FLAKY_BrowserAccelerators) {
+ BrowserAcceleratorsTest();
+}
- // Make sure the cursor is placed correctly.
- edit_view->GetSelectionBounds(&start, &end);
- EXPECT_EQ(old_text.size(), start);
- EXPECT_EQ(old_text.size(), end);
+// Flakily fails and times out on Win only. http://crbug.com/69941
+#if defined(OS_WIN)
+#define MAYBE_PopupAccelerators DISABLED_PopupAccelerators
+#else
+#define MAYBE_PopupAccelerators PopupAccelerators
+#endif
- // Insert one character at the end. Make sure we won't insert anything after
- // the special ZWS mark used in gtk implementation.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, false, false, false));
- EXPECT_EQ(old_text + L"a", edit_view->GetText());
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, MAYBE_PopupAccelerators) {
+ PopupAcceleratorsTest();
+}
- // Delete one character from the end. Make sure we won't delete the special
- // ZWS mark used in gtk implementation.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- EXPECT_EQ(old_text, edit_view->GetText());
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BackspaceInKeywordMode) {
+ BackspaceInKeywordModeTest();
+}
- edit_view->SelectAll(true);
- EXPECT_TRUE(edit_view->IsSelectAll());
- edit_view->GetSelectionBounds(&start, &end);
- EXPECT_EQ(0U, start);
- EXPECT_EQ(old_text.size(), end);
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, Escape) {
+ EscapeTest();
+}
- // Delete the content
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, false, false, false));
- EXPECT_TRUE(edit_view->IsSelectAll());
- edit_view->GetSelectionBounds(&start, &end);
- EXPECT_EQ(0U, start);
- EXPECT_EQ(0U, end);
- EXPECT_TRUE(edit_view->GetText().empty());
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DesiredTLD) {
+ DesiredTLDTest();
+}
- // Check if RevertAll() can set text and cursor correctly.
- edit_view->RevertAll();
- EXPECT_FALSE(edit_view->IsSelectAll());
- EXPECT_EQ(old_text, edit_view->GetText());
- edit_view->GetSelectionBounds(&start, &end);
- EXPECT_EQ(old_text.size(), start);
- EXPECT_EQ(old_text.size(), end);
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AltEnter) {
+ AltEnterTest();
}
-IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AcceptKeywordBySpace) {
- AutocompleteEditView* edit_view = NULL;
- ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EnterToSearch) {
+ EnterToSearchTest();
+}
- std::wstring text = UTF8ToWide(kSearchKeyword);
-
- // Trigger keyword hint mode.
- ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text, edit_view->GetText());
-
- // Trigger keyword mode by space.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_TRUE(edit_view->GetText().empty());
-
- // Revert to keyword hint mode.
- edit_view->model()->ClearKeyword(std::wstring());
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text, edit_view->GetText());
-
- // Keyword should also be accepted by typing an ideographic space.
- edit_view->OnBeforePossibleChange();
- edit_view->SetWindowTextAndCaretPos(text + L"\x3000", text.length() + 1);
- edit_view->OnAfterPossibleChange();
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_TRUE(edit_view->GetText().empty());
-
- // Revert to keyword hint mode.
- edit_view->model()->ClearKeyword(std::wstring());
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text, edit_view->GetText());
-
- // Keyword shouldn't be accepted by pasting.
- // Simulate pasting a whitespace to the end of content.
- edit_view->OnBeforePossibleChange();
- edit_view->model()->on_paste();
- edit_view->SetWindowTextAndCaretPos(text + L" ", text.length() + 1);
- edit_view->OnAfterPossibleChange();
- // Should be still in keyword hint mode.
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
-
- // Keyword shouldn't be accepted by pressing space with a trailing whitespace.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
-
- // Keyword shouldn't be accepted by deleting the trailing space.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, false, false, false));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
-
- // Keyword shouldn't be accepted by pressing space in the middle of content.
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, false, false, false));
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
-
- // Keyword shouldn't be accepted by pasting "foo bar".
- edit_view->SetUserText(std::wstring());
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_TRUE(edit_view->model()->keyword().empty());
-
- edit_view->OnBeforePossibleChange();
- edit_view->model()->on_paste();
- edit_view->SetWindowTextAndCaretPos(text + L" bar", text.length() + 4);
- edit_view->OnAfterPossibleChange();
- ASSERT_FALSE(edit_view->model()->is_keyword_hint());
- ASSERT_TRUE(edit_view->model()->keyword().empty());
- ASSERT_EQ(text + L" bar", edit_view->GetText());
-
- // Keyword shouldn't be accepted by pressing space with a selected range.
- edit_view->OnBeforePossibleChange();
- edit_view->OnInlineAutocompleteTextMaybeChanged(text + L" ", text.length());
- edit_view->OnAfterPossibleChange();
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EscapeToDefaultMatch) {
+ EscapeToDefaultMatchTest();
+}
- std::wstring::size_type start, end;
- edit_view->GetSelectionBounds(&start, &end);
- ASSERT_NE(start, end);
- ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, false, false, false));
- ASSERT_TRUE(edit_view->model()->is_keyword_hint());
- ASSERT_EQ(text, edit_view->model()->keyword());
- ASSERT_EQ(text + L" ", edit_view->GetText());
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BasicTextOperations) {
+ BasicTextOperationsTest();
+}
- edit_view->GetSelectionBounds(&start, &end);
- ASSERT_EQ(start, end);
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AcceptKeywordBySpace) {
+ AcceptKeywordBySpaceTest();
}
#if defined(OS_LINUX)
+// TODO(oshima): enable these tests for views-implmentation when
+// these featuers are supported.
+
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, UndoRedoLinux) {
ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
browser()->FocusLocationBar();
@@ -879,3 +938,50 @@ IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, PasteReplacingAll) {
ASSERT_EQ(L"abc", edit_view->GetText());
}
#endif
+
+#if defined(TOOLKIT_VIEWS)
+class AutocompleteEditViewViewsTest : public AutocompleteEditViewTest {
+ public:
+ AutocompleteEditViewViewsTest() {
+ views::NativeTextfieldViews::SetEnableTextfieldViews(true);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
+ FLAKY_BrowserAccelerators) {
+ BrowserAcceleratorsTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, MAYBE_PopupAccelerators) {
+ PopupAcceleratorsTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BackspaceInKeywordMode) {
+ BackspaceInKeywordModeTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, Escape) {
+ EscapeTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, DesiredTLD) {
+ DesiredTLDTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AltEnter) {
+ AltEnterTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EnterToSearch) {
+ EnterToSearchTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EscapeToDefaultMatch) {
+ EscapeToDefaultMatchTest();
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BasicTextOperations) {
+ BasicTextOperationsTest();
+}
+
+#endif
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
index f957137..07e79f5 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
@@ -38,9 +38,11 @@
#include "ui/base/animation/multi_animation.h"
#if defined(TOOLKIT_VIEWS)
+#include "chrome/browser/autocomplete/autocomplete_edit_view_views.h"
#include "chrome/browser/ui/gtk/accessible_widget_helper_gtk.h"
#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "views/controls/textfield/native_textfield_views.h"
#else
#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h"
#include "chrome/browser/ui/gtk/gtk_theme_provider.h"
@@ -854,6 +856,18 @@ AutocompleteEditView* AutocompleteEditViewGtk::Create(
CommandUpdater* command_updater,
bool popup_window_mode,
const views::View* location_bar) {
+ if (views::NativeTextfieldViews::IsTextfieldViewsEnabled()) {
+ AutocompleteEditViewViews* autocomplete =
+ new AutocompleteEditViewViews(controller,
+ toolbar_model,
+ profile,
+ command_updater,
+ popup_window_mode,
+ location_bar);
+ autocomplete->Init();
+ return autocomplete;
+ }
+
AutocompleteEditViewGtk* autocomplete =
new AutocompleteEditViewGtk(controller,
toolbar_model,
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_views.cc b/chrome/browser/autocomplete/autocomplete_edit_view_views.cc
new file mode 100644
index 0000000..357c7a2
--- /dev/null
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_views.cc
@@ -0,0 +1,635 @@
+// Copyright (c) 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.
+
+#include "chrome/browser/autocomplete/autocomplete_edit_view_views.h"
+
+#include "app/l10n_util.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/autocomplete/autocomplete_match.h"
+#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
+#include "chrome/browser/command_updater.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "chrome/common/notification_service.h"
+#include "gfx/font.h"
+#include "googleurl/src/gurl.h"
+#include "grit/generated_resources.h"
+#include "net/base/escape.h"
+#include "views/border.h"
+#include "views/fill_layout.h"
+
+namespace {
+
+// Textfield for autocomplete that intercepts events that are necessary
+// for AutocompleteEditViewViews.
+class AutocompleteTextfield : public views::Textfield {
+ public:
+ explicit AutocompleteTextfield(
+ AutocompleteEditViewViews* autocomplete_edit_view)
+ : views::Textfield(views::Textfield::STYLE_DEFAULT),
+ autocomplete_edit_view_(autocomplete_edit_view) {
+ DCHECK(autocomplete_edit_view_);
+ RemoveBorder();
+ }
+
+ // views::View implementation
+ virtual void DidGainFocus() {
+ views::Textfield::DidGainFocus();
+ autocomplete_edit_view_->HandleFocusIn();
+ }
+
+ virtual void WillLoseFocus() {
+ views::Textfield::WillLoseFocus();
+ autocomplete_edit_view_->HandleFocusOut();
+ }
+
+ virtual bool OnKeyPressed(const views::KeyEvent& e) {
+ bool handled = views::Textfield::OnKeyPressed(e);
+ return autocomplete_edit_view_->HandleAfterKeyEvent(e, handled) || handled;
+ }
+
+ virtual bool OnKeyReleased(const views::KeyEvent& e) {
+ return autocomplete_edit_view_->HandleKeyReleaseEvent(e);
+ }
+
+ virtual bool IsFocusable() const {
+ // Bypass Textfield::IsFocusable. The omnibox in popup window requires
+ // focus in order for text selection to work.
+ return views::View::IsFocusable();
+ }
+
+ private:
+ AutocompleteEditViewViews* autocomplete_edit_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutocompleteTextfield);
+};
+
+// Stores omnibox state for each tab.
+struct ViewState {
+ explicit ViewState(const views::TextRange& selection_range)
+ : selection_range(selection_range) {
+ }
+
+ // Range of selected text.
+ views::TextRange selection_range;
+};
+
+struct AutocompleteEditState {
+ AutocompleteEditState(const AutocompleteEditModel::State& model_state,
+ const ViewState& view_state)
+ : model_state(model_state),
+ view_state(view_state) {
+ }
+
+ const AutocompleteEditModel::State model_state;
+ const ViewState view_state;
+};
+
+// Returns a lazily initialized property bag accessor for saving our state in a
+// TabContents.
+PropertyAccessor<AutocompleteEditState>* GetStateAccessor() {
+ static PropertyAccessor<AutocompleteEditState> state;
+ return &state;
+}
+
+const int kAutocompleteVerticalMargin = 4;
+
+} // namespace
+
+AutocompleteEditViewViews::AutocompleteEditViewViews(
+ AutocompleteEditController* controller,
+ ToolbarModel* toolbar_model,
+ Profile* profile,
+ CommandUpdater* command_updater,
+ bool popup_window_mode,
+ const views::View* location_bar)
+ : model_(new AutocompleteEditModel(this, controller, profile)),
+ popup_view_(new AutocompletePopupContentsView(
+ gfx::Font(), this, model_.get(), profile, location_bar)),
+ controller_(controller),
+ toolbar_model_(toolbar_model),
+ command_updater_(command_updater),
+ popup_window_mode_(popup_window_mode),
+ security_level_(ToolbarModel::NONE),
+ delete_was_pressed_(false),
+ delete_at_end_pressed_(false) {
+ model_->SetPopupModel(popup_view_->GetModel());
+ set_border(views::Border::CreateEmptyBorder(kAutocompleteVerticalMargin, 0,
+ kAutocompleteVerticalMargin, 0));
+}
+
+AutocompleteEditViewViews::~AutocompleteEditViewViews() {
+ NotificationService::current()->Notify(
+ NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
+ Source<AutocompleteEditViewViews>(this),
+ NotificationService::NoDetails());
+ // Explicitly teardown members which have a reference to us. Just to be safe
+ // we want them to be destroyed before destroying any other internal state.
+ popup_view_.reset();
+ model_.reset();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews public:
+
+void AutocompleteEditViewViews::Init() {
+ // The height of the text view is going to change based on the font used. We
+ // don't want to stretch the height, and we want it vertically centered.
+ // TODO(oshima): make sure the above happens with views.
+ textfield_ = new AutocompleteTextfield(this);
+ textfield_->SetController(this);
+
+ if (popup_window_mode_)
+ textfield_->SetReadOnly(true);
+
+ // Manually invoke SetBaseColor() because TOOLKIT_VIEWS doesn't observe
+ // themes.
+ SetBaseColor();
+}
+
+void AutocompleteEditViewViews::SetBaseColor() {
+ // TODO(oshima): Implment style change.
+ NOTIMPLEMENTED();
+}
+
+bool AutocompleteEditViewViews::HandleAfterKeyEvent(
+ const views::KeyEvent& event,
+ bool handled) {
+ handling_key_press_ = false;
+ if (content_maybe_changed_by_key_press_)
+ OnAfterPossibleChange();
+
+ if (event.GetKeyCode() == ui::VKEY_RETURN) {
+ bool alt_held = event.IsAltDown();
+ model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
+ handled = true;
+ } else if (!handled && event.GetKeyCode() == ui::VKEY_ESCAPE) {
+ // We can handle the Escape key if textfield did not handle it.
+ // If it's not handled by us, then we need to propagate it up to the parent
+ // widgets, so that Escape accelerator can still work.
+ handled = model_->OnEscapeKeyPressed();
+ } else if (event.GetKeyCode() == ui::VKEY_CONTROL) {
+ // Omnibox2 can switch its contents while pressing a control key. To switch
+ // the contents of omnibox2, we notify the AutocompleteEditModel class when
+ // the control-key state is changed.
+ model_->OnControlKeyChanged(true);
+ } else if (!text_changed_ && event.GetKeyCode() == ui::VKEY_DELETE &&
+ event.IsShiftDown()) {
+ // If shift+del didn't change the text, we let this delete an entry from
+ // the popup. We can't check to see if the IME handled it because even if
+ // nothing is selected, the IME or the TextView still report handling it.
+ AutocompletePopupModel* popup_model = popup_view_->GetModel();
+ if (popup_model->IsOpen())
+ popup_model->TryDeletingCurrentItem();
+ } else if (!handled && event.GetKeyCode() == ui::VKEY_UP) {
+ model_->OnUpOrDownKeyPressed(-1);
+ handled = true;
+ } else if (!handled && event.GetKeyCode() == ui::VKEY_DOWN) {
+ model_->OnUpOrDownKeyPressed(1);
+ handled = true;
+ } else if (!handled &&
+ event.GetKeyCode() == ui::VKEY_TAB &&
+ !event.IsShiftDown() &&
+ !event.IsControlDown()) {
+ if (model_->is_keyword_hint() && !model_->keyword().empty()) {
+ model_->AcceptKeyword();
+ handled = true;
+ } else {
+ // TODO(Oshima): handle instant
+ }
+ }
+ // TODO(oshima): page up & down
+
+ return handled;
+}
+
+bool AutocompleteEditViewViews::HandleKeyReleaseEvent(
+ const views::KeyEvent& event) {
+ // Omnibox2 can switch its contents while pressing a control key. To switch
+ // the contents of omnibox2, we notify the AutocompleteEditModel class when
+ // the control-key state is changed.
+ if (event.GetKeyCode() == ui::VKEY_CONTROL) {
+ // TODO(oshima): investigate if we need to support keyboard with two
+ // controls. See autocomplete_edit_view_gtk.cc.
+ model_->OnControlKeyChanged(false);
+ return true;
+ }
+ return false;
+}
+
+void AutocompleteEditViewViews::HandleFocusIn() {
+ // TODO(oshima): Get control key state.
+ model_->OnSetFocus(false);
+ // Don't call controller_->OnSetFocus as this view has already
+ // acquired the focus.
+}
+
+void AutocompleteEditViewViews::HandleFocusOut() {
+ // TODO(oshima): we don't have native view. This requires
+ // further refactoring.
+ controller_->OnAutocompleteLosingFocus(NULL);
+ // Close the popup.
+ ClosePopup();
+ // Tell the model to reset itself.
+ model_->OnKillFocus();
+ controller_->OnKillFocus();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews, views::View implementation:
+
+bool AutocompleteEditViewViews::OnMousePressed(
+ const views::MouseEvent& event) {
+ if (event.IsLeftMouseButton()) {
+ // Button press event may change the selection, we need to record the change
+ // and report it to |model_| later when button is released.
+ OnBeforePossibleChange();
+ }
+ // Pass the event through to TextfieldViews.
+ return false;
+}
+
+void AutocompleteEditViewViews::Layout() {
+ gfx::Insets insets = GetInsets();
+ textfield_->SetBounds(insets.left(), insets.top(),
+ width() - insets.width(),
+ height() - insets.height());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews, AutocopmleteEditView implementation:
+
+AutocompleteEditModel* AutocompleteEditViewViews::model() {
+ return model_.get();
+}
+
+const AutocompleteEditModel* AutocompleteEditViewViews::model() const {
+ return model_.get();
+}
+
+void AutocompleteEditViewViews::SaveStateToTab(TabContents* tab) {
+ DCHECK(tab);
+
+ // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important.
+ AutocompleteEditModel::State model_state = model_->GetStateForTabSwitch();
+ views::TextRange selection;
+ textfield_->GetSelectedRange(&selection);
+ GetStateAccessor()->SetProperty(
+ tab->property_bag(),
+ AutocompleteEditState(model_state, ViewState(selection)));
+}
+
+void AutocompleteEditViewViews::Update(const TabContents* contents) {
+ // NOTE: We're getting the URL text here from the ToolbarModel.
+ bool visibly_changed_permanent_text =
+ model_->UpdatePermanentText(toolbar_model_->GetText());
+
+ ToolbarModel::SecurityLevel security_level =
+ toolbar_model_->GetSecurityLevel();
+ bool changed_security_level = (security_level != security_level_);
+ security_level_ = security_level;
+
+ // TODO(oshima): Copied from gtk implementation which is
+ // slightly different from WIN impl. Find out the correct implementation
+ // for views-implementation.
+ if (contents) {
+ RevertAll();
+ const AutocompleteEditState* state =
+ GetStateAccessor()->GetProperty(contents->property_bag());
+ if (state) {
+ model_->RestoreState(state->model_state);
+
+ // Move the marks for the cursor and the other end of the selection to
+ // the previously-saved offsets (but preserve PRIMARY).
+ textfield_->SelectRange(state->view_state.selection_range);
+ }
+ } else if (visibly_changed_permanent_text) {
+ RevertAll();
+ } else if (changed_security_level) {
+ EmphasizeURLComponents();
+ }
+}
+
+void AutocompleteEditViewViews::OpenURL(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url,
+ size_t selected_line,
+ const std::wstring& keyword) {
+ if (!url.is_valid())
+ return;
+
+ model_->OpenURL(url, disposition, transition, alternate_nav_url,
+ selected_line, keyword);
+}
+
+std::wstring AutocompleteEditViewViews::GetText() const {
+ // TODO(oshima): IME support
+ return UTF16ToWide(textfield_->text());
+}
+
+bool AutocompleteEditViewViews::IsEditingOrEmpty() const {
+ return model_->user_input_in_progress() || (GetTextLength() == 0);
+}
+
+int AutocompleteEditViewViews::GetIcon() const {
+ return IsEditingOrEmpty() ?
+ AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) :
+ toolbar_model_->GetIcon();
+}
+
+void AutocompleteEditViewViews::SetUserText(const std::wstring& text) {
+ SetUserText(text, text, true);
+}
+
+void AutocompleteEditViewViews::SetUserText(const std::wstring& text,
+ const std::wstring& display_text,
+ bool update_popup) {
+ model_->SetUserText(text);
+ SetWindowTextAndCaretPos(display_text, display_text.length());
+ if (update_popup)
+ UpdatePopup();
+ TextChanged();
+}
+
+void AutocompleteEditViewViews::SetWindowTextAndCaretPos(
+ const std::wstring& text,
+ size_t caret_pos) {
+ const views::TextRange range(caret_pos, caret_pos);
+ SetTextAndSelectedRange(text, range);
+}
+
+void AutocompleteEditViewViews::SetForcedQuery() {
+ const std::wstring current_text(GetText());
+ const size_t start = current_text.find_first_not_of(kWhitespaceWide);
+ if (start == std::wstring::npos || (current_text[start] != '?')) {
+ SetUserText(L"?");
+ } else {
+ SelectRange(current_text.size(), start + 1);
+ }
+}
+
+bool AutocompleteEditViewViews::IsSelectAll() {
+ // TODO(oshima): IME support.
+ return textfield_->text() == textfield_->GetSelectedText();
+}
+
+bool AutocompleteEditViewViews::DeleteAtEndPressed() {
+ return delete_at_end_pressed_;
+}
+
+void AutocompleteEditViewViews::GetSelectionBounds(
+ std::wstring::size_type* start,
+ std::wstring::size_type* end) {
+ views::TextRange range;
+ textfield_->GetSelectedRange(&range);
+ *start = static_cast<size_t>(range.end());
+ *end = static_cast<size_t>(range.start());
+}
+
+void AutocompleteEditViewViews::SelectAll(bool reversed) {
+ if (reversed)
+ SelectRange(GetTextLength(), 0);
+ else
+ SelectRange(0, GetTextLength());
+}
+
+void AutocompleteEditViewViews::RevertAll() {
+ ClosePopup();
+ model_->Revert();
+ TextChanged();
+}
+
+void AutocompleteEditViewViews::UpdatePopup() {
+ model_->SetInputInProgress(true);
+ if (!model_->has_focus())
+ return;
+
+ // Don't inline autocomplete when the caret/selection isn't at the end of
+ // the text, or in the middle of composition.
+ views::TextRange sel;
+ textfield_->GetSelectedRange(&sel);
+ bool no_inline_autocomplete = sel.GetMax() < GetTextLength();
+
+ // TODO(oshima): Support IME. Don't show autocomplete if IME has some text.
+ model_->StartAutocomplete(!sel.is_empty(), no_inline_autocomplete);
+}
+
+void AutocompleteEditViewViews::ClosePopup() {
+ if (popup_view_->GetModel()->IsOpen())
+ controller_->OnAutocompleteWillClosePopup();
+
+ popup_view_->GetModel()->StopAutocomplete();
+}
+
+void AutocompleteEditViewViews::SetFocus() {
+ // In views-implementation, the focus is on textfield rather than
+ // AutocompleteEditView.
+ textfield_->RequestFocus();
+}
+
+void AutocompleteEditViewViews::OnTemporaryTextMaybeChanged(
+ const std::wstring& display_text,
+ bool save_original_selection) {
+ if (save_original_selection)
+ textfield_->GetSelectedRange(&saved_temporary_selection_);
+
+ SetWindowTextAndCaretPos(display_text, display_text.length());
+ TextChanged();
+}
+
+bool AutocompleteEditViewViews::OnInlineAutocompleteTextMaybeChanged(
+ const std::wstring& display_text,
+ size_t user_text_length) {
+ if (display_text == GetText())
+ return false;
+ views::TextRange range(display_text.size(), user_text_length);
+ SetTextAndSelectedRange(display_text, range);
+ TextChanged();
+ return true;
+}
+
+void AutocompleteEditViewViews::OnRevertTemporaryText() {
+ textfield_->SelectRange(saved_temporary_selection_);
+ TextChanged();
+}
+
+void AutocompleteEditViewViews::OnBeforePossibleChange() {
+ // Record our state.
+ text_before_change_ = GetText();
+ textfield_->GetSelectedRange(&sel_before_change_);
+}
+
+bool AutocompleteEditViewViews::OnAfterPossibleChange() {
+ // OnAfterPossibleChange should be called once per modification,
+ // and we should ignore if this is called while a key event is being handled
+ // because OnAfterPossibleChagne will be called after the key event is
+ // actually handled.
+ if (handling_key_press_) {
+ content_maybe_changed_by_key_press_ = true;
+ return false;
+ }
+ views::TextRange new_sel;
+ textfield_->GetSelectedRange(&new_sel);
+
+ size_t length = GetTextLength();
+ bool at_end_of_edit = (new_sel.start() == length && new_sel.end() == length);
+
+ // See if the text or selection have changed since OnBeforePossibleChange().
+ std::wstring new_text = GetText();
+ text_changed_ = (new_text != text_before_change_);
+ bool selection_differs = !sel_before_change_.Equals(new_sel);
+
+ // When the user has deleted text, we don't allow inline autocomplete. Make
+ // sure to not flag cases like selecting part of the text and then pasting
+ // (or typing) the prefix of that selection. (We detect these by making
+ // sure the caret, which should be after any insertion, hasn't moved
+ // forward of the old selection start.)
+ bool just_deleted_text =
+ (text_before_change_.length() > new_text.length()) &&
+ (new_sel.start() <= sel_before_change_.GetMin());
+
+ delete_at_end_pressed_ = false;
+
+ bool something_changed = model_->OnAfterPossibleChange(new_text,
+ selection_differs, text_changed_, just_deleted_text, at_end_of_edit);
+
+ // If only selection was changed, we don't need to call |controller_|'s
+ // OnChanged() method, which is called in TextChanged().
+ // But we still need to call EmphasizeURLComponents() to make sure the text
+ // attributes are updated correctly.
+ if (something_changed && text_changed_) {
+ TextChanged();
+ } else if (selection_differs) {
+ EmphasizeURLComponents();
+ } else if (delete_was_pressed_ && at_end_of_edit) {
+ delete_at_end_pressed_ = true;
+ controller_->OnChanged();
+ }
+ delete_was_pressed_ = false;
+
+ return something_changed;
+}
+
+gfx::NativeView AutocompleteEditViewViews::GetNativeView() const {
+ return GetWidget()->GetNativeView();
+}
+
+CommandUpdater* AutocompleteEditViewViews::GetCommandUpdater() {
+ return command_updater_;
+}
+
+views::View* AutocompleteEditViewViews::AddToView(views::View* parent) {
+ parent->AddChildView(this);
+ AddChildView(textfield_);
+ return this;
+}
+
+int AutocompleteEditViewViews::TextWidth() const {
+ // TODO(oshima): add horizontal margin.
+ return textfield_->font().GetStringWidth(textfield_->text());
+}
+
+bool AutocompleteEditViewViews::IsImeComposing() const {
+ return false;
+}
+
+bool AutocompleteEditViewViews::CommitInstantSuggestion(
+ const std::wstring& typed_text,
+ const std::wstring& suggested_text) {
+ model_->FinalizeInstantQuery(typed_text, suggested_text);
+ return true;
+}
+
+void AutocompleteEditViewViews::SetInstantSuggestion(const string16& input) {
+ NOTIMPLEMENTED();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews, NotificationObserver implementation:
+
+void AutocompleteEditViewViews::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::BROWSER_THEME_CHANGED);
+ SetBaseColor();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews, Textfield::Controller implementation:
+
+void AutocompleteEditViewViews::ContentsChanged(views::Textfield* sender,
+ const string16& new_contents) {
+ if (handling_key_press_)
+ content_maybe_changed_by_key_press_ = true;
+}
+
+bool AutocompleteEditViewViews::HandleKeyEvent(
+ views::Textfield* textfield,
+ const views::KeyEvent& event) {
+ delete_was_pressed_ = event.GetKeyCode() == ui::VKEY_DELETE;
+
+ // Reset |text_changed_| before passing the key event on to the text view.
+ text_changed_ = false;
+ OnBeforePossibleChange();
+ handling_key_press_ = true;
+ content_maybe_changed_by_key_press_ = false;
+
+ if (event.GetKeyCode() == ui::VKEY_BACK) {
+ // Checks if it's currently in keyword search mode.
+ if (model_->is_keyword_hint() || model_->keyword().empty())
+ return false;
+ // If there is selection, let textfield handle the backspace.
+ if (!textfield_->GetSelectedText().empty())
+ return false;
+ // If not at the begining of the text, let textfield handle the backspace.
+ if (textfield_->GetCursorPosition())
+ return false;
+ model_->ClearKeyword(GetText());
+ return true;
+ }
+
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditViewViews, private:
+
+size_t AutocompleteEditViewViews::GetTextLength() const {
+ // TODO(oshima): Support instant, IME.
+ return textfield_->text().length();
+}
+
+void AutocompleteEditViewViews::EmphasizeURLComponents() {
+ // TODO(oshima): Update URL visual style
+ NOTIMPLEMENTED();
+}
+
+void AutocompleteEditViewViews::TextChanged() {
+ EmphasizeURLComponents();
+ controller_->OnChanged();
+}
+
+void AutocompleteEditViewViews::SetTextAndSelectedRange(
+ const std::wstring& text,
+ const views::TextRange& range) {
+ if (text != GetText())
+ textfield_->SetText(WideToUTF16(text));
+ textfield_->SelectRange(range);
+}
+
+string16 AutocompleteEditViewViews::GetSelectedText() const {
+ // TODO(oshima): Support instant, IME.
+ return textfield_->GetSelectedText();
+}
+
+void AutocompleteEditViewViews::SelectRange(size_t caret, size_t end) {
+ const views::TextRange range(caret, end);
+ textfield_->SelectRange(range);
+}
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_views.h b/chrome/browser/autocomplete/autocomplete_edit_view_views.h
new file mode 100644
index 0000000..9c17ad8
--- /dev/null
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_views.h
@@ -0,0 +1,207 @@
+// Copyright (c) 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.
+
+#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_VIEWS_H_
+#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_VIEWS_H_
+#pragma once
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/browser/ui/toolbar/toolbar_model.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/page_transition_types.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/view.h"
+#include "webkit/glue/window_open_disposition.h"
+
+class AutocompleteEditController;
+class AutocompleteEditModel;
+class AutocompletePopupView;
+class Profile;
+class TabContents;
+
+// Views-implementation of AutocompleteEditView. This is based on
+// gtk implementation. The following features are not yet supported.
+//
+// IME supoprt.
+// LTR support.
+// Selection behavior.
+// Cut,copy and paste behavior.
+// URL styles (strikestrough insecure scheme, emphasize host).
+// Custom context menu for omnibox.
+// Instant.
+class AutocompleteEditViewViews : public views::View,
+ public AutocompleteEditView,
+ public NotificationObserver,
+ public views::Textfield::Controller {
+ public:
+ AutocompleteEditViewViews(AutocompleteEditController* controller,
+ ToolbarModel* toolbar_model,
+ Profile* profile,
+ CommandUpdater* command_updater,
+ bool popup_window_mode,
+ const views::View* location_bar);
+ virtual ~AutocompleteEditViewViews();
+
+ // Initialize, create the underlying views, etc;
+ void Init();
+
+ // Sets the colors of the text view according to the theme.
+ void SetBaseColor();
+
+ // Called after key even is handled either by HandleKeyEvent or by Textfield.
+ bool HandleAfterKeyEvent(const views::KeyEvent& event, bool handled);
+
+ // Called when KeyRelease event is generated on textfield.
+ bool HandleKeyReleaseEvent(const views::KeyEvent& event);
+
+ // Called when Focus is set/unset on textfield.
+ void HandleFocusIn();
+ void HandleFocusOut();
+
+ // Implements views::View
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void Layout();
+
+ // Implement the AutocompleteEditView interface.
+ virtual AutocompleteEditModel* model();
+ virtual const AutocompleteEditModel* model() const;
+
+ virtual void SaveStateToTab(TabContents* tab);
+
+ virtual void Update(const TabContents* tab_for_state_restoring);
+
+ virtual void OpenURL(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url,
+ size_t selected_line,
+ const std::wstring& keyword);
+
+ virtual std::wstring GetText() const;
+
+ virtual bool IsEditingOrEmpty() const;
+ virtual int GetIcon() const;
+ virtual void SetUserText(const std::wstring& text);
+ virtual void SetUserText(const std::wstring& text,
+ const std::wstring& display_text,
+ bool update_popup);
+ virtual void SetWindowTextAndCaretPos(const std::wstring& text,
+ size_t caret_pos);
+ virtual void SetForcedQuery();
+ virtual bool IsSelectAll();
+ virtual bool DeleteAtEndPressed();
+ virtual void GetSelectionBounds(std::wstring::size_type* start,
+ std::wstring::size_type* end);
+ virtual void SelectAll(bool reversed);
+ virtual void RevertAll();
+ virtual void UpdatePopup();
+ virtual void ClosePopup();
+ virtual void SetFocus();
+ virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
+ bool save_original_selection);
+ virtual bool OnInlineAutocompleteTextMaybeChanged(
+ const std::wstring& display_text, size_t user_text_length);
+ virtual void OnRevertTemporaryText();
+ virtual void OnBeforePossibleChange();
+ virtual bool OnAfterPossibleChange();
+ virtual gfx::NativeView GetNativeView() const;
+ virtual CommandUpdater* GetCommandUpdater();
+ virtual views::View* AddToView(views::View* parent);
+ virtual int TextWidth() const;
+ virtual bool IsImeComposing() const;
+ virtual bool CommitInstantSuggestion(const std::wstring& typed_text,
+ const std::wstring& suggested_text);
+ virtual void SetInstantSuggestion(const string16& input);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Overridden from Textfield::Controller
+ virtual void ContentsChanged(views::Textfield* sender,
+ const string16& new_contents);
+ virtual bool HandleKeyEvent(views::Textfield* sender,
+ const views::KeyEvent& key_event);
+
+ private:
+ // Return the number of characers in the current buffer.
+ size_t GetTextLength() const;
+
+ // Try to parse the current text as a URL and colorize the components.
+ void EmphasizeURLComponents();
+
+ // Internally invoked whenever the text changes in some way.
+ void TextChanged();
+
+ // Update the field with |text| and set the selection.
+ void SetTextAndSelectedRange(const std::wstring& text,
+ const views::TextRange& range);
+
+ // Returns the selected text.
+ string16 GetSelectedText() const;
+
+ // Selects the text given by |caret| and |end|.
+ void SelectRange(size_t caret, size_t end);
+
+ views::Textfield* textfield_;
+
+ scoped_ptr<AutocompleteEditModel> model_;
+ scoped_ptr<AutocompletePopupView> popup_view_;
+ AutocompleteEditController* controller_;
+ ToolbarModel* toolbar_model_;
+
+ // The object that handles additional command functionality exposed on the
+ // edit, such as invoking the keyword editor.
+ CommandUpdater* command_updater_;
+
+ // When true, the location bar view is read only and also is has a slightly
+ // different presentation (smaller font size). This is used for popups.
+ bool popup_window_mode_;
+
+ ToolbarModel::SecurityLevel security_level_;
+
+ // Selection at the point where the user started using the
+ // arrows to move around in the popup.
+ views::TextRange saved_temporary_selection_;
+
+ // Tracking state before and after a possible change.
+ std::wstring text_before_change_;
+ views::TextRange sel_before_change_;
+
+ // TODO(oshima): following flags are copied from gtk implementation.
+ // It should be possible to refactor this class to simplify flags and
+ // logic. I'll work on this refactoring once all features are completed.
+
+ // Indicates whether the IME changed the text. It's possible for the IME to
+ // handle a key event but not change the text contents (e.g., when pressing
+ // shift+del with no selection).
+ bool text_changed_;
+
+ // Was delete pressed?
+ bool delete_was_pressed_;
+
+ // Was the delete key pressed with an empty selection at the end of the edit?
+ bool delete_at_end_pressed_;
+
+ // Indicates if we are handling a key press event.
+ bool handling_key_press_;
+
+ // Indicates if omnibox's content maybe changed by a key press event, so that
+ // we need to call OnAfterPossibleChange() after handling the event.
+ // This flag should be set for changes directly caused by a key press event,
+ // including changes to content text, selection range and preedit string.
+ // Changes caused by function calls like SetUserText() should not affect this
+ // flag.
+ bool content_maybe_changed_by_key_press_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutocompleteEditViewViews);
+};
+
+#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_VIEWS_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index bde19ab..45b09f9 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -117,6 +117,8 @@
'browser/autocomplete/autocomplete_edit_view_mac.mm',
'browser/autocomplete/autocomplete_edit_view_win.cc',
'browser/autocomplete/autocomplete_edit_view_win.h',
+ 'browser/autocomplete/autocomplete_edit_view_views.cc',
+ 'browser/autocomplete/autocomplete_edit_view_views.h',
'browser/autocomplete/autocomplete_match.cc',
'browser/autocomplete/autocomplete_match.h',
'browser/autocomplete/autocomplete_popup_model.cc',