diff options
author | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-14 16:52:06 +0000 |
---|---|---|
committer | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-14 16:52:06 +0000 |
commit | d17734b4d8dcaa8203541e528064158d25e35df9 (patch) | |
tree | b417892a49bfe89354eea8d0b39991f88d8b67f6 /chrome | |
parent | d202055fbb939e08ac9c8668c4f4f5b67ad5847c (diff) | |
download | chromium_src-d17734b4d8dcaa8203541e528064158d25e35df9.zip chromium_src-d17734b4d8dcaa8203541e528064158d25e35df9.tar.gz chromium_src-d17734b4d8dcaa8203541e528064158d25e35df9.tar.bz2 |
Support specified JSON as argument to setSuggestions().
Maintain backwards compatibility with the array of strings.
TEST=interactive_ui_tests --gtest_filter=InstantTest.*
BUG=None
Review URL: http://codereview.chromium.org/6310003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71450 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/instant/instant_browsertest.cc | 108 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.h | 1 | ||||
-rw-r--r-- | chrome/renderer/searchbox_extension.cc | 63 | ||||
-rw-r--r-- | chrome/renderer/searchbox_extension.h | 2 | ||||
-rw-r--r-- | chrome/test/data/instant/search.html | 12 |
5 files changed, 165 insertions, 21 deletions
diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc index 816b4a3..2409068 100644 --- a/chrome/browser/instant/instant_browsertest.cc +++ b/chrome/browser/instant/instant_browsertest.cc @@ -9,6 +9,8 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/instant/instant_controller.h" +#include "chrome/browser/instant/instant_loader.h" +#include "chrome/browser/instant/instant_loader_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" @@ -22,6 +24,9 @@ #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" +#define EXPECT_STR_EQ(ascii, utf16) \ + EXPECT_EQ(ASCIIToWide(ascii), UTF16ToWide(utf16)) + class InstantTest : public InProcessBrowserTest { public: InstantTest() @@ -111,11 +116,26 @@ class InstantTest : public InProcessBrowserTest { NotificationType::INSTANT_CONTROLLER_SHOWN); } + const string16& GetSuggestion() const { + return browser()->instant()->loader_manager_-> + current_loader()->complete_suggested_text_; + } + void SendKey(ui::KeyboardCode key) { ASSERT_TRUE(ui_test_utils::SendKeyPressSync( browser(), key, false, false, false, false)); } + void SetSuggestionsJavascriptArgument(TabContents* tab_contents, + const std::string& argument) { + std::string script = StringPrintf( + "window.setSuggestionsArgument = %s;", argument.c_str()); + ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( + tab_contents->render_view_host(), + std::wstring(), + UTF8ToWide(script))); + } + bool GetStringFromJavascript(TabContents* tab_contents, const std::string& function, std::string* result) { @@ -247,10 +267,9 @@ class InstantTest : public InProcessBrowserTest { }; // TODO(tonyg): Add the following tests: -// 1. Test that setSuggestions() works. -// 2. Test that the search box API is not populated for pages other than the -// default search provider. -// 3. Test resize events. +// - Test that the search box API is not populated for pages other than the +// default search provider. +// - Test resize events. // Verify that the onchange event is dispatched upon typing in the box. IN_PROC_BROWSER_TEST_F(InstantTest, OnChangeEvent) { @@ -266,6 +285,87 @@ IN_PROC_BROWSER_TEST_F(InstantTest, OnChangeEvent) { GetSearchStateAsString(preview_)); } +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsArrayOfStrings) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument(preview_, "['abcde', 'unused']"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("abcde", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptyArray) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument(preview_, "[]"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsValidJson) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument( + preview_, + "{suggestions:[{value:'abcdefg'},{value:'unused'}]}"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("abcdefg", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsInvalidSuggestions) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument( + preview_, + "{suggestions:{value:'abcdefg'}}"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptyJson) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument(preview_, "{}"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptySuggestions) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument(preview_, "{suggestions:[]}"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("", GetSuggestion()); +} + +IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptySuggestion) { + ASSERT_TRUE(test_server()->Start()); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(SetupLocationBar()); + ASSERT_NO_FATAL_FAILURE(SetupPreview()); + + SetSuggestionsJavascriptArgument(preview_, "{suggestions:[{}]}"); + ASSERT_NO_FATAL_FAILURE(SetLocationBarText(L"abc")); + EXPECT_STR_EQ("", GetSuggestion()); +} + // Verify instant preview is shown correctly for a non-search query. IN_PROC_BROWSER_TEST_F(InstantTest, ShowPreviewNonSearch) { ASSERT_TRUE(test_server()->Start()); diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h index 8be48af..83b0e84 100644 --- a/chrome/browser/instant/instant_loader.h +++ b/chrome/browser/instant/instant_loader.h @@ -94,6 +94,7 @@ class InstantLoader : public NotificationObserver { private: friend class InstantLoaderManagerTest; + friend class InstantTest; class FrameLoadObserver; class PaintObserverImpl; class TabContentsDelegateImpl; diff --git a/chrome/renderer/searchbox_extension.cc b/chrome/renderer/searchbox_extension.cc index 180e92c..2e26864 100644 --- a/chrome/renderer/searchbox_extension.cc +++ b/chrome/renderer/searchbox_extension.cc @@ -276,25 +276,62 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( return v8::Int32::New(render_view->searchbox().height); } +// Accepts a single argument in form: +// { +// suggestions: [ +// { +// value: "..." +// } +// ] +// } // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( const v8::Arguments& args) { - if (!args.Length() || !args[0]->IsArray()) return v8::Undefined(); - std::vector<std::string> suggestions; - v8::Array* suggestions_arg = static_cast<v8::Array*>(*args[0]); - uint32_t length = suggestions_arg->Length(); - for (uint32_t i = 0; i < length; i++) { - std::string suggestion = *v8::String::Utf8Value( - suggestions_arg->Get(v8::Integer::New(i))->ToString()); - if (!suggestion.length()) continue; - suggestions.push_back(suggestion); - } - RenderView* render_view = GetRenderView(); - if (!render_view) return v8::Undefined(); + if (args.Length() && args[0]->IsArray()) { + // For backwards compatibility, also accept an array of strings. + // TODO(tonyg): Remove this when it is confirmed to be unused. + v8::Array* suggestions_array = static_cast<v8::Array*>(*args[0]); + uint32_t length = suggestions_array->Length(); + for (uint32_t i = 0; i < length; i++) { + std::string suggestion = *v8::String::Utf8Value( + suggestions_array->Get(v8::Integer::New(i))->ToString()); + if (!suggestion.length()) continue; + suggestions.push_back(suggestion); + } + } else if (args.Length() && args[0]->IsObject()) { + // Standard version, object argument. + v8::Object* suggestion_json = static_cast<v8::Object*>(*args[0]); + v8::Local<v8::Value> suggestions_field = + suggestion_json->Get(v8::String::New("suggestions")); + + if (suggestions_field->IsArray()) { + v8::Local<v8::Array> suggestions_array = + suggestions_field.As<v8::Array>(); + + uint32_t length = suggestions_array->Length(); + for (uint32_t i = 0; i < length; i++) { + v8::Local<v8::Value> suggestion_value = + suggestions_array->Get(v8::Integer::New(i)); + if (!suggestion_value->IsObject()) continue; + + v8::Local<v8::Object> suggestion_object = + suggestion_value.As<v8::Object>(); + v8::Local<v8::Value> suggestion_object_value = + suggestion_object->Get(v8::String::New("value")); + if (!suggestion_object_value->IsString()) continue; + + std::string suggestion = *v8::String::Utf8Value( + suggestion_object_value->ToString()); + if (!suggestion.length()) continue; + suggestions.push_back(suggestion); + } + } + } - render_view->SetSuggestions(suggestions); + if (RenderView* render_view = GetRenderView()) + render_view->SetSuggestions(suggestions); return v8::Undefined(); } diff --git a/chrome/renderer/searchbox_extension.h b/chrome/renderer/searchbox_extension.h index 61d82b7c..82a8ed9 100644 --- a/chrome/renderer/searchbox_extension.h +++ b/chrome/renderer/searchbox_extension.h @@ -19,7 +19,7 @@ class WebFrame; namespace extensions_v8 { // Reference implementation of the SearchBox API as described in: -// http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-October/028818.html +// http://dev.chromium.org/searchbox class SearchBoxExtension { public: // Returns the v8::Extension object handling searchbox bindings. Returns null diff --git a/chrome/test/data/instant/search.html b/chrome/test/data/instant/search.html index 60c8a2a..7e68897 100644 --- a/chrome/test/data/instant/search.html +++ b/chrome/test/data/instant/search.html @@ -15,18 +15,24 @@ var searchBox = window.chrome.searchBox || {}; window.beforeLoadSearchBox = {}; for (var prop in searchBox) window.beforeLoadSearchBox[prop] = searchBox[prop]; +window.setSuggestionsArgument = { + suggestions: [ + { value: "abcdef" } + ] +}; + window.chrome.searchBox.onsubmit = function() { - searchBox.setSuggestions(["abcdef"]); + searchBox.setSuggestions(setSuggestionsArgument); window.onsubmitcalls++; }; window.chrome.searchBox.onchange = function() { - searchBox.setSuggestions(["abcdef"]); + searchBox.setSuggestions(setSuggestionsArgument); window.onchangecalls++; }; window.chrome.searchBox.oncancel = function() { - searchBox.setSuggestions(["abcdef"]); + searchBox.setSuggestions(setSuggestionsArgument); window.oncancelcalls++; }; |