diff options
author | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 15:48:39 +0000 |
---|---|---|
committer | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 15:48:39 +0000 |
commit | ce833284bfd1b0a5db62e0f3c25f48af70ae8784 (patch) | |
tree | 641d0e058901b544626b3503ff5ce06da08ba926 /chrome/renderer | |
parent | 26cce058ecd57c1da05a9a95a277da91e9be8f43 (diff) | |
download | chromium_src-ce833284bfd1b0a5db62e0f3c25f48af70ae8784.zip chromium_src-ce833284bfd1b0a5db62e0f3c25f48af70ae8784.tar.gz chromium_src-ce833284bfd1b0a5db62e0f3c25f48af70ae8784.tar.bz2 |
Implement new SearchBox API along side existing API.
Add some tests.
BUG=none
TEST=interactive_ui_tests --gtest_filter=InstantTest.*
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65061 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_thread.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 56 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 18 | ||||
-rw-r--r-- | chrome/renderer/search_extension.cc | 4 | ||||
-rw-r--r-- | chrome/renderer/searchbox.cc | 18 | ||||
-rw-r--r-- | chrome/renderer/searchbox.h | 25 | ||||
-rw-r--r-- | chrome/renderer/searchbox_extension.cc | 381 | ||||
-rw-r--r-- | chrome/renderer/searchbox_extension.h | 42 |
8 files changed, 540 insertions, 6 deletions
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index cde829c..a43a6ec 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -66,6 +66,7 @@ #include "chrome/renderer/renderer_webidbfactory_impl.h" #include "chrome/renderer/renderer_webkitclient_impl.h" #include "chrome/renderer/search_extension.h" +#include "chrome/renderer/searchbox_extension.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/renderer/user_script_slave.h" #include "ipc/ipc_channel_handle.h" @@ -853,6 +854,7 @@ void RenderThread::EnsureWebKitInitialized() { RegisterExtension(extensions_v8::LoadTimesExtension::Get(), false); RegisterExtension(extensions_v8::ChromeAppExtension::Get(), false); RegisterExtension(extensions_v8::ExternalExtension::Get(), false); + RegisterExtension(extensions_v8::SearchBoxExtension::Get(), false); v8::Extension* search_extension = extensions_v8::SearchExtension::Get(); // search_extension is null if not enabled. if (search_extension) diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 9e3bc83..0b300a1 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -80,6 +80,7 @@ #include "chrome/renderer/render_widget_fullscreen_pepper.h" #include "chrome/renderer/renderer_webapplicationcachehost_impl.h" #include "chrome/renderer/renderer_webstoragenamespace_impl.h" +#include "chrome/renderer/searchbox_extension.h" #include "chrome/renderer/speech_input_dispatcher.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/renderer/user_script_idle_scheduler.h" @@ -837,6 +838,12 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground) IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode, OnEnablePreferredSizeChangedMode) + IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxChange, OnSearchBoxChange) + IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxSubmit, OnSearchBoxSubmit) + IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxCancel, OnSearchBoxCancel) + IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxResize, OnSearchBoxResize) + IPC_MESSAGE_HANDLER(ViewMsg_DetermineIfPageSupportsInstant, + OnDetermineIfPageSupportsInstant) IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows, OnDisableScrollbarsForSmallWindows) IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs) @@ -4330,9 +4337,9 @@ WebFrame* RenderView::GetChildFrame(const std::wstring& xpath) const { return frame; } -void RenderView::SetSuggestResult(const std::string& suggest) { - // Explicitly allow empty strings to be sent to the browser. - Send(new ViewHostMsg_SetSuggestResult(routing_id_, page_id_, suggest)); +void RenderView::SetSuggestions(const std::vector<std::string>& suggestions) { + // Explicitly allow empty vector to be sent to the browser. + Send(new ViewHostMsg_SetSuggestions(routing_id_, page_id_, suggestions)); } void RenderView::EvaluateScript(const string16& frame_xpath, @@ -4570,6 +4577,49 @@ void RenderView::OnEnablePreferredSizeChangedMode(int flags) { } } +void RenderView::OnSearchBoxChange(const string16& value, + int selection_start, + int selection_end) { + search_box_.value = value; + search_box_.selection_start = selection_start; + search_box_.selection_end = selection_end; + if (!webview() || !webview()->mainFrame()) + return; + extensions_v8::SearchBoxExtension::DispatchChange(webview()->mainFrame()); +} + +void RenderView::OnSearchBoxSubmit(const string16& value, bool verbatim) { + search_box_.value = value; + search_box_.verbatim = verbatim; + if (!webview() || !webview()->mainFrame()) + return; + extensions_v8::SearchBoxExtension::DispatchSubmit(webview()->mainFrame()); +} + +void RenderView::OnSearchBoxCancel() { + search_box_.verbatim = false; + if (!webview() || !webview()->mainFrame()) + return; + extensions_v8::SearchBoxExtension::DispatchCancel(webview()->mainFrame()); +} + +void RenderView::OnSearchBoxResize(const gfx::Rect& bounds) { + search_box_.x = bounds.x(); + search_box_.y = bounds.y(); + search_box_.width = bounds.width(); + search_box_.height = bounds.height(); + if (!webview() || !webview()->mainFrame()) + return; + extensions_v8::SearchBoxExtension::DispatchResize(webview()->mainFrame()); +} + +void RenderView::OnDetermineIfPageSupportsInstant(const string16& value) { + search_box_.value = value; + bool result = extensions_v8::SearchBoxExtension::PageSupportsInstant( + webview()->mainFrame()); + Send(new ViewHostMsg_InstantSupportDetermined(routing_id_, page_id_, result)); +} + void RenderView::OnDisableScrollbarsForSmallWindows( const gfx::Size& disable_scrollbar_size_limit) { disable_scrollbars_size_limit_ = disable_scrollbar_size_limit; diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index b835293..54a995f 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -32,6 +32,7 @@ #include "chrome/renderer/pepper_plugin_delegate_impl.h" #include "chrome/renderer/render_widget.h" #include "chrome/renderer/renderer_webcookiejar_impl.h" +#include "chrome/renderer/searchbox.h" #include "chrome/renderer/translate_helper.h" #include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h" @@ -229,6 +230,10 @@ class RenderView : public RenderWidget, disable_scrollbars_size_limit_.height() <= height)); } + const SearchBox& searchbox() const { + return search_box_; + } + // Called from JavaScript window.external.AddSearchProvider() to add a // keyword for a provider described in the given OpenSearch document. void AddSearchProvider(const std::string& url, @@ -239,8 +244,8 @@ class RenderView : public RenderWidget, GetSearchProviderInstallState(WebKit::WebFrame* frame, const std::string& url); - // Sends ViewHostMsg_SetSuggestResult to the browser. - void SetSuggestResult(const std::string& suggest); + // Sends ViewHostMsg_SetSuggestions to the browser. + void SetSuggestions(const std::vector<std::string>& suggestions); // Evaluates a string of JavaScript in a particular frame. void EvaluateScript(const string16& frame_xpath, @@ -823,6 +828,13 @@ class RenderView : public RenderWidget, const gfx::Point& screen_pt, WebKit::WebDragOperationsMask operations_allowed); void OnEnablePreferredSizeChangedMode(int flags); + void OnSearchBoxChange(const string16& value, + int selection_start, + int selection_end); + void OnSearchBoxSubmit(const string16& value, bool verbatim); + void OnSearchBoxCancel(); + void OnSearchBoxResize(const gfx::Rect& bounds); + void OnDetermineIfPageSupportsInstant(const string16& value); void OnEnableViewSourceMode(); void OnExecuteCode(const ViewMsg_ExecuteCode_Params& params); void OnExecuteEditCommand(const std::string& name, const std::string& value); @@ -1235,6 +1247,8 @@ class RenderView : public RenderWidget, // The text selection the last time DidChangeSelection got called. std::string last_selection_; + SearchBox search_box_; + // View ---------------------------------------------------------------------- // Type of view attached with RenderView. See view_types.h diff --git a/chrome/renderer/search_extension.cc b/chrome/renderer/search_extension.cc index 1ce6296..f14cda7 100644 --- a/chrome/renderer/search_extension.cc +++ b/chrome/renderer/search_extension.cc @@ -78,7 +78,9 @@ v8::Handle<v8::Value> SearchExtensionWrapper::SetSuggestResult( RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); - render_view->SetSuggestResult(std::string(*v8::String::Utf8Value(args[0]))); + std::vector<std::string> suggestions; + suggestions.push_back(std::string(*v8::String::Utf8Value(args[0]))); + render_view->SetSuggestions(suggestions); return v8::Undefined(); } diff --git a/chrome/renderer/searchbox.cc b/chrome/renderer/searchbox.cc new file mode 100644 index 0000000..6766f25 --- /dev/null +++ b/chrome/renderer/searchbox.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/searchbox.h" + +SearchBox::SearchBox() + : verbatim(false), + selection_start(0), + selection_end(0), + x(0), + y(0), + width(0), + height(0) { +} + +SearchBox::~SearchBox() { +} diff --git a/chrome/renderer/searchbox.h b/chrome/renderer/searchbox.h new file mode 100644 index 0000000..d09c73a --- /dev/null +++ b/chrome/renderer/searchbox.h @@ -0,0 +1,25 @@ +// Copyright (c) 2010 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_RENDERER_SEARCHBOX_H_ +#define CHROME_RENDERER_SEARCHBOX_H_ +#pragma once + +#include "base/string16.h" + +struct SearchBox { + SearchBox(); + ~SearchBox(); + + string16 value; + bool verbatim; + uint32 selection_start; + uint32 selection_end; + uint32 x; + uint32 y; + uint32 width; + uint32 height; +}; + +#endif // CHROME_RENDERER_SEARCHBOX_H_ diff --git a/chrome/renderer/searchbox_extension.cc b/chrome/renderer/searchbox_extension.cc new file mode 100644 index 0000000..40073fa --- /dev/null +++ b/chrome/renderer/searchbox_extension.cc @@ -0,0 +1,381 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/searchbox_extension.h" + +#include "base/command_line.h" +#include "base/string_split.h" +#include "base/stringprintf.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/render_messages_params.h" +#include "chrome/renderer/render_view.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebScriptSource.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "v8/include/v8.h" + +using WebKit::WebFrame; +using WebKit::WebScriptSource; +using WebKit::WebString; +using WebKit::WebView; + +namespace extensions_v8 { + +static const char kSearchBoxExtensionName[] = "v8/SearchBox"; + +static const char kSearchBoxExtensionScript[] = + "var chrome;" + "if (!chrome)" + " chrome = {};" + "if (!chrome.searchBox) {" + " chrome.searchBox = new function() {" + " native function GetValue();" + " native function GetVerbatim();" + " native function GetSelectionStart();" + " native function GetSelectionEnd();" + " native function GetX();" + " native function GetY();" + " native function GetWidth();" + " native function GetHeight();" + " native function SetSuggestions();" + " this.__defineGetter__('value', GetValue);" + " this.__defineGetter__('verbatim', GetVerbatim);" + " this.__defineGetter__('selectionStart', GetSelectionStart);" + " this.__defineGetter__('selectionEnd', GetSelectionEnd);" + " this.__defineGetter__('x', GetX);" + " this.__defineGetter__('y', GetY);" + " this.__defineGetter__('width', GetWidth);" + " this.__defineGetter__('height', GetHeight);" + " this.setSuggestions = function(text) {" + " SetSuggestions(text);" + " };" + " this.onchange = null;" + " this.onsubmit = null;" + " this.oncancel = null;" + " this.onresize = null;" + " };" + "}"; + +static const char kChangeEventName[] = "chrome.searchBox.onchange"; + +static const char kSubmitEventName[] = "chrome.searchBox.onsubmit"; + +static const char kCancelEventName[] = "chrome.searchBox.oncancel"; + +static const char kResizeEventName[] = "chrome.searchBox.onresize"; + +// Deprecated API support. +// TODO(tonyg): Remove these when they are no longer used. +// ---------------------------------------------------------------------------- +// Script sent as the user is typing and the provider supports instant. +// Params: +// . the text the user typed. +// TODO: add support for the 2nd and 3rd params. +static const char kUserInputScript[] = + "if (window.chrome.userInput)" + " window.chrome.userInput(" + " window.chrome.searchBox.value," + " 0," + " 0);"; + +// Script sent when the page is committed and the provider supports instant. +// Params: +// . the text the user typed. +// . boolean indicating if the user pressed enter to accept the text. +static const char kUserDoneScript[] = + "if (window.chrome.userWantsQuery)" + " window.chrome.userWantsQuery(" + " window.chrome.searchBox.value," + " window.chrome.searchBox.verbatim);"; + +// Script sent when the bounds of the omnibox changes and the provider supports +// instant. The params are the bounds relative to the origin of the preview +// (x, y, width, height). +static const char kSetOmniboxBoundsScript[] = + "if (window.chrome.setDropdownDimensions)" + " window.chrome.setDropdownDimensions(" + " window.chrome.searchBox.x," + " window.chrome.searchBox.y," + " window.chrome.searchBox.width," + " window.chrome.searchBox.height);"; + +// We first send this script down to determine if the page supports instant. +static const char kSupportsInstantScript[] = + "if (window.chrome.sv) true; else false;"; + +// The google.y.first array is a list of functions which are to be executed +// after the external JavaScript used by Google web search loads. The deprecated +// API requires setDropdownDimensions and userInput to be invoked after +// the external JavaScript loads. So if they are not already registered, we add +// them to the array of functions the page will execute after load. This tight +// coupling discourages proliferation of the deprecated API. +static const char kInitScript[] = + "(function() {" + "var initScript = function(){%s%s};" + "if (window.chrome.setDropdownDimensions)" + " initScript();" + "else if (window.google && window.google.y)" + " window.google.y.first.push(initScript);" + "})();"; +// ---------------------------------------------------------------------------- + +class SearchBoxExtensionWrapper : public v8::Extension { + public: + SearchBoxExtensionWrapper(); + + // Allows v8's javascript code to call the native functions defined + // in this class for window.chrome. + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name); + + // Helper function to find the RenderView. May return NULL. + static RenderView* GetRenderView(); + + // Gets the value of the user's search query. + static v8::Handle<v8::Value> GetValue(const v8::Arguments& args); + + // Gets whether the |value| should be considered final -- as opposed to a + // partial match. This may be set if the user clicks a suggestion, presses + // forward delete, or in other cases where Chrome overrides. + static v8::Handle<v8::Value> GetVerbatim(const v8::Arguments& args); + + // Gets the start of the selection in the search box. + static v8::Handle<v8::Value> GetSelectionStart(const v8::Arguments& args); + + // Gets the end of the selection in the search box. + static v8::Handle<v8::Value> GetSelectionEnd(const v8::Arguments& args); + + // Gets the x coordinate (relative to |window|) of the left edge of the + // region of the search box that overlaps the window. + static v8::Handle<v8::Value> GetX(const v8::Arguments& args); + + // Gets the y coordinate (relative to |window|) of the right edge of the + // region of the search box that overlaps the window. + static v8::Handle<v8::Value> GetY(const v8::Arguments& args); + + // Gets the width of the region of the search box that overlaps the window. + static v8::Handle<v8::Value> GetWidth(const v8::Arguments& args); + + // Gets the height of the region of the search box that overlaps the window. + static v8::Handle<v8::Value> GetHeight(const v8::Arguments& args); + + // Sets ordered suggestions. Valid for current |value|. + static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args); + + private: + DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); +}; + +SearchBoxExtensionWrapper::SearchBoxExtensionWrapper() + : v8::Extension(kSearchBoxExtensionName, kSearchBoxExtensionScript) {} + +v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("GetValue"))) { + return v8::FunctionTemplate::New(GetValue); + } else if (name->Equals(v8::String::New("GetVerbatim"))) { + return v8::FunctionTemplate::New(GetVerbatim); + } else if (name->Equals(v8::String::New("GetSelectionStart"))) { + return v8::FunctionTemplate::New(GetSelectionStart); + } else if (name->Equals(v8::String::New("GetSelectionEnd"))) { + return v8::FunctionTemplate::New(GetSelectionEnd); + } else if (name->Equals(v8::String::New("GetX"))) { + return v8::FunctionTemplate::New(GetX); + } else if (name->Equals(v8::String::New("GetY"))) { + return v8::FunctionTemplate::New(GetY); + } else if (name->Equals(v8::String::New("GetWidth"))) { + return v8::FunctionTemplate::New(GetWidth); + } else if (name->Equals(v8::String::New("GetHeight"))) { + return v8::FunctionTemplate::New(GetHeight); + } else if (name->Equals(v8::String::New("SetSuggestions"))) { + return v8::FunctionTemplate::New(SetSuggestions); + } + return v8::Handle<v8::FunctionTemplate>(); +} + +// static +RenderView* SearchBoxExtensionWrapper::GetRenderView() { + WebFrame* webframe = WebFrame::frameForEnteredContext(); + DCHECK(webframe) << "There should be an active frame since we just got " + "a native function called."; + if (!webframe) return NULL; + + WebView* webview = webframe->view(); + if (!webview) return NULL; // can happen during closing + + return RenderView::FromWebView(webview); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetValue( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::String::New( + reinterpret_cast<const uint16_t*>(render_view->searchbox().value.c_str()), + render_view->searchbox().value.length()); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetVerbatim( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Boolean::New(render_view->searchbox().verbatim); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionStart( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().selection_start); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSelectionEnd( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().selection_end); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetX( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().x); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetY( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().y); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetWidth( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().width); +} + +// static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetHeight( + const v8::Arguments& args) { + RenderView* render_view = GetRenderView(); + if (!render_view) return v8::Undefined(); + return v8::Int32::New(render_view->searchbox().height); +} + +// 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(); + + render_view->SetSuggestions(suggestions); + return v8::Undefined(); +} + +// static +bool Dispatch(WebFrame* frame, const std::string& event_name) { + DCHECK(frame) << "Dispatch requires frame"; + if (!frame) return false; + + v8::HandleScope handle_scope; + v8::Local<v8::Context> context = frame->mainWorldScriptContext(); + v8::Context::Scope context_scope(context); + + v8::Local<v8::Value> value = + context->Global()->Get(v8::String::New("window")); + std::vector<std::string> components; + base::SplitStringDontTrim(event_name, '.', &components); + for (size_t i = 0; i < components.size(); ++i) { + if (!value.IsEmpty() && value->IsObject()) + value = value->ToObject()->Get(v8::String::New(components[i].c_str())); + } + if (value.IsEmpty() || !value->IsFunction()) + return false; + + v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); + if (function.IsEmpty()) + return false; + + function->Call(v8::Object::New(), 0, NULL); + return true; +} + +// static +void SearchBoxExtension::DispatchChange(WebFrame* frame) { + if (Dispatch(frame, kChangeEventName)) + return; + frame->executeScript(WebScriptSource(kUserInputScript)); +} + +// static +void SearchBoxExtension::DispatchSubmit(WebFrame* frame) { + if (Dispatch(frame, kSubmitEventName)) + return; + frame->executeScript(WebScriptSource(kUserDoneScript)); +} + +// static +void SearchBoxExtension::DispatchCancel(WebFrame* frame) { + if (Dispatch(frame, kCancelEventName)) + return; + frame->executeScript(WebScriptSource(kUserDoneScript)); +} + +// static +void SearchBoxExtension::DispatchResize(WebFrame* frame) { + if (Dispatch(frame, kResizeEventName)) + return; + frame->executeScript(WebScriptSource(kSetOmniboxBoundsScript)); +} + +// static +bool SearchBoxExtension::PageSupportsInstant(WebFrame* frame) { + DCHECK(frame) << "PageSupportsInstant requires frame"; + if (!frame) return false; + + bool supports_deprecated_api = frame->executeScriptAndReturnValue( + WebScriptSource(kSupportsInstantScript))->BooleanValue(); + // TODO(tonyg): Add way of detecting instant support to SearchBox API. + bool supports_searchbox_api = supports_deprecated_api; + + // The deprecated API needs to notify the page of events it may have missed. + // This isn't necessary in the SearchBox API, since the page can query the + // API at any time. + static std::string init_script( + StringPrintf(kInitScript, kSetOmniboxBoundsScript, kUserInputScript)); + if (supports_deprecated_api) { + frame->executeScript(WebScriptSource(WebString::fromUTF8(init_script))); + } + + return supports_searchbox_api || supports_deprecated_api; +} + +// static +v8::Extension* SearchBoxExtension::Get() { + return new SearchBoxExtensionWrapper(); +} + +} // namespace extensions_v8 diff --git a/chrome/renderer/searchbox_extension.h b/chrome/renderer/searchbox_extension.h new file mode 100644 index 0000000..61d82b7c --- /dev/null +++ b/chrome/renderer/searchbox_extension.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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_RENDERER_SEARCHBOX_EXTENSION_H_ +#define CHROME_RENDERER_SEARCHBOX_EXTENSION_H_ +#pragma once + +#include "base/basictypes.h" + +namespace v8 { +class Extension; +} + +namespace WebKit { +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 +class SearchBoxExtension { + public: + // Returns the v8::Extension object handling searchbox bindings. Returns null + // if match-preview is not enabled. Caller takes ownership of returned object. + static v8::Extension* Get(); + + static void DispatchChange(WebKit::WebFrame* frame); + static void DispatchSubmit(WebKit::WebFrame* frame); + static void DispatchCancel(WebKit::WebFrame* frame); + static void DispatchResize(WebKit::WebFrame* frame); + + static bool PageSupportsInstant(WebKit::WebFrame* frame); + + private: + DISALLOW_COPY_AND_ASSIGN(SearchBoxExtension); +}; + +} // namespace extensions_v8 + +#endif // CHROME_RENDERER_SEARCHBOX_EXTENSION_H_ |