summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authortonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-14 16:52:06 +0000
committertonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-14 16:52:06 +0000
commitd17734b4d8dcaa8203541e528064158d25e35df9 (patch)
treeb417892a49bfe89354eea8d0b39991f88d8b67f6 /chrome
parentd202055fbb939e08ac9c8668c4f4f5b67ad5847c (diff)
downloadchromium_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.cc108
-rw-r--r--chrome/browser/instant/instant_loader.h1
-rw-r--r--chrome/renderer/searchbox_extension.cc63
-rw-r--r--chrome/renderer/searchbox_extension.h2
-rw-r--r--chrome/test/data/instant/search.html12
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++;
};