Commit d17734b4 authored by tonyg@chromium.org's avatar tonyg@chromium.org

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
parent d202055f
......@@ -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());
......
......@@ -94,6 +94,7 @@ class InstantLoader : public NotificationObserver {
private:
friend class InstantLoaderManagerTest;
friend class InstantTest;
class FrameLoadObserver;
class PaintObserverImpl;
class TabContentsDelegateImpl;
......
......@@ -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();
}
......
......@@ -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
......
......@@ -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++;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment