summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-07 21:35:03 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-07 21:35:03 +0000
commit0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5 (patch)
treea9ce0236b330fab3f39124c52fa0c1f184eb3965
parent5e91242859811aef980a929253e6c33eb2cfec6e (diff)
downloadchromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.zip
chromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.tar.gz
chromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.tar.bz2
Landing this again as I cannot reproduce the perf regression locally.
Will investigate on the bot. TBR=nsylvain Review URL: http://codereview.chromium.org/9700 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5018 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/render_view_host.cc44
-rw-r--r--chrome/browser/render_view_host.h7
-rw-r--r--chrome/browser/render_view_host_delegate.h5
-rw-r--r--chrome/browser/render_widget_helper.cc6
-rw-r--r--chrome/browser/render_widget_helper.h2
-rw-r--r--chrome/browser/render_widget_host_view_win.cc3
-rw-r--r--chrome/browser/render_widget_host_view_win.h8
-rw-r--r--chrome/browser/resource_message_filter.cc6
-rw-r--r--chrome/browser/resource_message_filter.h2
-rw-r--r--chrome/browser/web_contents_view.cc6
-rw-r--r--chrome/browser/web_contents_view.h6
-rw-r--r--chrome/browser/web_contents_view_win.cc7
-rw-r--r--chrome/browser/web_contents_view_win.h3
-rw-r--r--chrome/common/render_messages_internal.h23
-rw-r--r--chrome/renderer/render_view.cc36
-rw-r--r--chrome/renderer/render_view.h17
-rw-r--r--chrome/renderer/render_widget.cc14
-rw-r--r--chrome/renderer/render_widget.h9
-rw-r--r--chrome/renderer/render_widget_unittest.cc6
-rw-r--r--webkit/build/glue/glue.vcproj8
-rw-r--r--webkit/build/port/port.vcproj4
-rw-r--r--webkit/glue/SConscript1
-rw-r--r--webkit/glue/autocomplete_input_listener.h1
-rw-r--r--webkit/glue/chrome_client_impl.cc8
-rw-r--r--webkit/glue/chrome_client_impl.h3
-rw-r--r--webkit/glue/form_autocomplete_listener.cc37
-rw-r--r--webkit/glue/form_autocomplete_listener.h46
-rw-r--r--webkit/glue/password_autocomplete_listener.cc1
-rw-r--r--webkit/glue/webframeloaderclient_impl.cc60
-rw-r--r--webkit/glue/webframeloaderclient_impl.h8
-rw-r--r--webkit/glue/webplugin_impl_mac.mm3
-rw-r--r--webkit/glue/webview.h7
-rw-r--r--webkit/glue/webview_delegate.h11
-rw-r--r--webkit/glue/webview_impl.cc214
-rw-r--r--webkit/glue/webview_impl.h16
-rw-r--r--webkit/port/page/chromium/ChromeClientChromium.h2
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.cpp133
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.h82
-rw-r--r--webkit/webkit.xcodeproj/project.pbxproj8
39 files changed, 739 insertions, 124 deletions
diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc
index 6c127a7..71c9574 100644
--- a/chrome/browser/render_view_host.cc
+++ b/chrome/browser/render_view_host.cc
@@ -696,6 +696,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_ShouldClose_ACK, OnMsgShouldCloseACK);
IPC_MESSAGE_HANDLER(ViewHostMsg_UnloadListenerChanged,
OnUnloadListenerChanged);
+ IPC_MESSAGE_HANDLER(ViewHostMsg_QueryFormFieldAutofill,
+ OnQueryFormFieldAutofill)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg))
IPC_END_MESSAGE_MAP_EX()
@@ -725,10 +727,11 @@ void RenderViewHost::OnMsgCreateWindow(int route_id,
view->CreateNewWindow(route_id, modal_dialog_event);
}
-void RenderViewHost::OnMsgCreateWidget(int route_id) {
+void RenderViewHost::OnMsgCreateWidget(int route_id,
+ bool focus_on_show) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (view)
- view->CreateNewWidget(route_id);
+ view->CreateNewWidget(route_id, focus_on_show);
}
void RenderViewHost::OnMsgShowView(int route_id,
@@ -1226,6 +1229,43 @@ void RenderViewHost::OnUnloadListenerChanged(bool has_listener) {
has_unload_listener_ = has_listener;
}
+void RenderViewHost::OnQueryFormFieldAutofill(const std::wstring& field_name,
+ const std::wstring& user_text,
+ int64 node_id,
+ int request_id) {
+ // TODO(jcampan): this is where the suggestions should be queried from the
+ // database. The sample code commented below is left here in the meantime for
+ // testing purpose.
+#ifndef TEST_AUTOFILL
+ static std::vector<std::wstring>* suggestions = NULL;
+ if (!suggestions) {
+ suggestions = new std::vector<std::wstring>();
+ suggestions->push_back(L"Alice");
+ suggestions->push_back(L"Jay");
+ suggestions->push_back(L"Jason");
+ suggestions->push_back(L"Jasmine");
+ suggestions->push_back(L"Jamel");
+ suggestions->push_back(L"Jamelo");
+ suggestions->push_back(L"Volvo");
+ suggestions->push_back(L"Volswagen");
+ }
+
+
+ std::vector<std::wstring> result;
+ for (std::vector<std::wstring>::iterator iter = suggestions->begin();
+ iter != suggestions->end(); ++iter) {
+ if (StartsWith(*iter, user_text, false))
+ result.push_back(*iter);
+ }
+ Send(new ViewMsg_AutofillSuggestions(routing_id_,
+ node_id, request_id, result, 0));
+#else
+ Send(new ViewMsg_AutofillSuggestions(routing_id_,
+ node_id, request_id,
+ std::vector<std::wstring>(), 0));
+#endif
+}
+
void RenderViewHost::NotifyRendererUnresponsive() {
// If the debugger is attached, we're going to be unresponsive anytime it's
// stopped at a breakpoint.
diff --git a/chrome/browser/render_view_host.h b/chrome/browser/render_view_host.h
index ae0a729..6c9fede 100644
--- a/chrome/browser/render_view_host.h
+++ b/chrome/browser/render_view_host.h
@@ -399,7 +399,7 @@ class RenderViewHost : public RenderWidgetHost {
// IPC message handlers:
void OnMsgCreateWindow(int route_id, HANDLE modal_dialog_event);
- void OnMsgCreateWidget(int route_id);
+ void OnMsgCreateWidget(int route_id, bool focus_on_show);
void OnMsgShowView(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
@@ -498,7 +498,10 @@ class RenderViewHost : public RenderWidgetHost {
const webkit_glue::WebApplicationInfo& info);
void OnMsgShouldCloseACK(bool proceed);
void OnUnloadListenerChanged(bool has_handler);
-
+ void OnQueryFormFieldAutofill(const std::wstring& field_name,
+ const std::wstring& user_text,
+ int64 node_id,
+ int request_id);
virtual void NotifyRendererUnresponsive();
virtual void NotifyRendererResponsive();
diff --git a/chrome/browser/render_view_host_delegate.h b/chrome/browser/render_view_host_delegate.h
index 27910d7..4230438 100644
--- a/chrome/browser/render_view_host_delegate.h
+++ b/chrome/browser/render_view_host_delegate.h
@@ -60,7 +60,10 @@ class RenderViewHostDelegate {
// The page is trying to open a new widget (e.g. a select popup). The
// widget should be created associated with the given route, but it should
// not be shown yet. That should happen in response to ShowCreatedWidget.
- virtual void CreateNewWidget(int route_id) = 0;
+ // If |focus_on_show| is true, the focus is given to the widget when shown,
+ // otherwise the focus is not changed.
+ virtual void CreateNewWidget(int route_id,
+ bool focus_on_show) = 0;
// Show a previously created page with the specified disposition and bounds.
// The window is identified by the route_id passed to CreateNewWindow.
diff --git a/chrome/browser/render_widget_helper.cc b/chrome/browser/render_widget_helper.cc
index d6e2bd7..4b87080 100644
--- a/chrome/browser/render_widget_helper.cc
+++ b/chrome/browser/render_widget_helper.cc
@@ -218,9 +218,11 @@ void RenderWidgetHelper::CreateNewWindow(int opener_id,
this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}
-void RenderWidgetHelper::CreateNewWidget(int opener_id, int* route_id) {
+void RenderWidgetHelper::CreateNewWidget(int opener_id,
+ bool focus_on_show,
+ int* route_id) {
*route_id = GetNextRoutingID();
- ViewHostMsg_CreateWidgetWithRoute msg(opener_id, *route_id);
+ ViewHostMsg_CreateWidgetWithRoute msg(opener_id, *route_id, focus_on_show);
ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &RenderWidgetHelper::OnSimulateReceivedMessage, msg));
}
diff --git a/chrome/browser/render_widget_helper.h b/chrome/browser/render_widget_helper.h
index 7b6295f..c09462a 100644
--- a/chrome/browser/render_widget_helper.h
+++ b/chrome/browser/render_widget_helper.h
@@ -113,7 +113,7 @@ class RenderWidgetHelper :
void CreateNewWindow(int opener_id, bool user_gesture, int* route_id,
HANDLE* modal_dialog_event, HANDLE render_process);
- void CreateNewWidget(int opener_id, int* route_id);
+ void CreateNewWidget(int opener_id, bool focus_on_show, int* route_id);
private:
// A class used to proxy a paint message. PaintMsgProxy objects are created
diff --git a/chrome/browser/render_widget_host_view_win.cc b/chrome/browser/render_widget_host_view_win.cc
index ece55bc..3c86595 100644
--- a/chrome/browser/render_widget_host_view_win.cc
+++ b/chrome/browser/render_widget_host_view_win.cc
@@ -77,7 +77,8 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
tooltip_showing_(false),
shutdown_factory_(this),
parent_hwnd_(NULL),
- is_loading_(false) {
+ is_loading_(false),
+ focus_on_show_(true) {
render_widget_host_->set_view(this);
renderer_accessible_ =
CommandLine().HasSwitch(switches::kEnableRendererAccessibility);
diff --git a/chrome/browser/render_widget_host_view_win.h b/chrome/browser/render_widget_host_view_win.h
index ff609f3..d1b7730 100644
--- a/chrome/browser/render_widget_host_view_win.h
+++ b/chrome/browser/render_widget_host_view_win.h
@@ -65,6 +65,11 @@ class RenderWidgetHostViewWin :
close_on_deactivate_ = close_on_deactivate;
}
+ void set_focus_on_show(bool focus) {
+ focus_on_show_ = focus;
+ }
+ bool focus_on_show() const { return focus_on_show_; }
+
void set_parent_hwnd(HWND parent) { parent_hwnd_ = parent; }
DECLARE_WND_CLASS_EX(kRenderWidgetHostHWNDClass, CS_DBLCLKS, 0);
@@ -260,6 +265,9 @@ class RenderWidgetHostViewWin :
// value returns true for is_null() if we are not recording whiteout times.
base::TimeTicks whiteout_start_time_;
+ // Whether the window should get focus when shown. Default is true.
+ bool focus_on_show_;
+
// Whether the renderer is made accessible.
// TODO(jcampan): http://b/issue?id=1432077 This is a temporary work-around
// until that bug is fixed.
diff --git a/chrome/browser/resource_message_filter.cc b/chrome/browser/resource_message_filter.cc
index 2e25e92..24eb964 100644
--- a/chrome/browser/resource_message_filter.cc
+++ b/chrome/browser/resource_message_filter.cc
@@ -234,8 +234,10 @@ void ResourceMessageFilter::OnMsgCreateWindow(int opener_id,
modal_dialog_event, render_handle_);
}
-void ResourceMessageFilter::OnMsgCreateWidget(int opener_id, int* route_id) {
- render_widget_helper_->CreateNewWidget(opener_id, route_id);
+void ResourceMessageFilter::OnMsgCreateWidget(int opener_id,
+ bool focus_on_show,
+ int* route_id) {
+ render_widget_helper_->CreateNewWidget(opener_id, focus_on_show, route_id);
}
void ResourceMessageFilter::OnRequestResource(
diff --git a/chrome/browser/resource_message_filter.h b/chrome/browser/resource_message_filter.h
index 7dd3513..1b068e4 100644
--- a/chrome/browser/resource_message_filter.h
+++ b/chrome/browser/resource_message_filter.h
@@ -77,7 +77,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
private:
void OnMsgCreateWindow(int opener_id, bool user_gesture, int* route_id,
HANDLE* modal_dialog_event);
- void OnMsgCreateWidget(int opener_id, int* route_id);
+ void OnMsgCreateWidget(int opener_id, bool focus_on_show, int* route_id);
void OnRequestResource(const IPC::Message& msg, int request_id,
const ViewHostMsg_Resource_Request& request);
void OnCancelRequest(int request_id);
diff --git a/chrome/browser/web_contents_view.cc b/chrome/browser/web_contents_view.cc
index 28dd88b..931e36c 100644
--- a/chrome/browser/web_contents_view.cc
+++ b/chrome/browser/web_contents_view.cc
@@ -10,9 +10,11 @@ void WebContentsView::CreateNewWindow(int route_id, HANDLE modal_dialog_event) {
modal_dialog_event);
}
-void WebContentsView::CreateNewWidget(int route_id) {
+void WebContentsView::CreateNewWidget(int route_id,
+ bool focus_on_show) {
// Save the created widget associated with the route so we can show it later.
- pending_widget_views_[route_id] = CreateNewWidgetInternal(route_id);
+ pending_widget_views_[route_id] = CreateNewWidgetInternal(route_id,
+ focus_on_show);
}
void WebContentsView::ShowCreatedWindow(int route_id,
diff --git a/chrome/browser/web_contents_view.h b/chrome/browser/web_contents_view.h
index 6ebf84c..e6b24c2 100644
--- a/chrome/browser/web_contents_view.h
+++ b/chrome/browser/web_contents_view.h
@@ -172,7 +172,8 @@ class WebContentsView : public RenderViewHostDelegate::View {
// the Show functions rather than the route ID.
virtual WebContents* CreateNewWindowInternal(int route_id,
HANDLE modal_dialog_event) = 0;
- virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id) = 0;
+ virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id,
+ bool focus_on_show) = 0;
virtual void ShowCreatedWindowInternal(WebContents* new_web_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
@@ -185,7 +186,8 @@ class WebContentsView : public RenderViewHostDelegate::View {
// do some book-keeping associated with the request. The request is then
// forwarded to *Internal which does platform-specific work.
virtual void CreateNewWindow(int route_id, HANDLE modal_dialog_event);
- virtual void CreateNewWidget(int route_id);
+ virtual void CreateNewWidget(int route_id,
+ bool focus_on_show);
virtual void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
diff --git a/chrome/browser/web_contents_view_win.cc b/chrome/browser/web_contents_view_win.cc
index 082fb89..3ba7173 100644
--- a/chrome/browser/web_contents_view_win.cc
+++ b/chrome/browser/web_contents_view_win.cc
@@ -378,7 +378,8 @@ WebContents* WebContentsViewWin::CreateNewWindowInternal(
}
RenderWidgetHostView* WebContentsViewWin::CreateNewWidgetInternal(
- int route_id) {
+ int route_id,
+ bool focus_on_show) {
// Create the widget and its associated view.
// TODO(brettw) can widget creation be cross-platform?
RenderWidgetHost* widget_host =
@@ -394,6 +395,7 @@ RenderWidgetHostView* WebContentsViewWin::CreateNewWidgetInternal(
widget_view->set_parent_hwnd(
web_contents_->render_widget_host_view()->GetPluginHWND());
widget_view->set_close_on_deactivate(true);
+ widget_view->set_focus_on_show(focus_on_show);
return widget_view;
}
@@ -438,7 +440,8 @@ void WebContentsViewWin::ShowCreatedWidgetInternal(
widget_host_view_win->MoveWindow(initial_pos.x(), initial_pos.y(),
initial_pos.width(), initial_pos.height(),
TRUE);
- widget_host_view_win->ShowWindow(SW_SHOW);
+ widget_host_view_win->ShowWindow(widget_host_view_win->focus_on_show() ?
+ SW_SHOW : SW_SHOWNOACTIVATE);
widget_host->Init();
}
diff --git a/chrome/browser/web_contents_view_win.h b/chrome/browser/web_contents_view_win.h
index d1ea193..ca03829 100644
--- a/chrome/browser/web_contents_view_win.h
+++ b/chrome/browser/web_contents_view_win.h
@@ -56,7 +56,8 @@ class WebContentsViewWin : public WebContentsView,
// Backend implementation of RenderViewHostDelegate::View.
virtual WebContents* CreateNewWindowInternal(
int route_id, HANDLE modal_dialog_event);
- virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id);
+ virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id,
+ bool focus_on_show);
virtual void ShowCreatedWindowInternal(WebContents* new_web_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 579a318..a4098a0 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -463,6 +463,14 @@ IPC_BEGIN_MESSAGES(View, 1)
// into a full window).
IPC_MESSAGE_ROUTED0(ViewMsg_DisassociateFromPopupCount)
+ // Reply to the ViewHostMsg_QueryFormFieldAutofill message with the autofill
+ // suggestions.
+ IPC_MESSAGE_ROUTED4(ViewMsg_AutofillSuggestions,
+ int64 /* id of the text input field */,
+ int /* id of the request message */,
+ std::vector<std::wstring> /* suggestions */,
+ int /* index of default suggestion */)
+
IPC_END_MESSAGES(View)
@@ -484,8 +492,9 @@ IPC_BEGIN_MESSAGES(ViewHost, 2)
// Similar to ViewHostMsg_CreateView, except used for sub-widgets, like
// <select> dropdowns. This message is sent to the WebContents that
// contains the widget being created.
- IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_CreateWidget,
+ IPC_SYNC_MESSAGE_CONTROL2_1(ViewHostMsg_CreateWidget,
int /* opener_id */,
+ bool /* focus on show */,
int /* route_id */)
// These two messages are sent as a result of the above two, in the browser
@@ -494,8 +503,9 @@ IPC_BEGIN_MESSAGES(ViewHost, 2)
int /* route_id */,
HANDLE /* modal_dialog_event */)
- IPC_MESSAGE_ROUTED1(ViewHostMsg_CreateWidgetWithRoute,
- int /* route_id */)
+ IPC_MESSAGE_ROUTED2(ViewHostMsg_CreateWidgetWithRoute,
+ int /* route_id */,
+ bool /* focus on show */)
// These two messages are sent to the parent RenderViewHost to display the
// page/widget that was created by CreateView/CreateWidget. routing_id
@@ -1064,4 +1074,11 @@ IPC_BEGIN_MESSAGES(ViewHost, 2)
HWND /* window */,
gfx::Rect /* Out: Window location */)
+ // Queries the browser for suggestion for autofill in a form input field.
+ IPC_MESSAGE_ROUTED4(ViewHostMsg_QueryFormFieldAutofill,
+ std::wstring /* field name */,
+ std::wstring /* user entered text */,
+ int64 /* id of the text input field */,
+ int /* id of this message */)
+
IPC_END_MESSAGES(ViewHost)
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 7cebc16..cbae9d0 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -142,7 +142,7 @@ class RenderViewExtraRequestData : public WebRequest::ExtraData {
///////////////////////////////////////////////////////////////////////////////
RenderView::RenderView()
- : RenderWidget(RenderThread::current()),
+ : RenderWidget(RenderThread::current(), true),
is_loading_(false),
page_id_(-1),
last_page_id_sent_to_browser_(-1),
@@ -161,7 +161,8 @@ RenderView::RenderView()
has_unload_listener_(false),
decrement_shared_popup_at_destruction_(false),
greasemonkey_enabled_(false),
- waiting_for_create_window_ack_(false) {
+ waiting_for_create_window_ack_(false),
+ form_field_autofill_request_id_(0) {
resource_dispatcher_ = new ResourceDispatcher(this);
#ifdef CHROME_PERSONALIZATION
personalization_ = Personalization::CreateRendererPersonalization();
@@ -384,6 +385,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
OnMessageFromExternalHost)
IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
OnDisassociateFromPopupCount)
+ IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
+ OnReceivedAutofillSuggestions)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
IPC_END_MESSAGE_MAP()
@@ -1664,6 +1667,29 @@ void RenderView::OnUnloadListenerChanged(WebView* webview, WebFrame* webframe) {
}
}
+void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
+ const std::wstring& text,
+ int64 node_id) {
+ static int message_id_counter = 0;
+ form_field_autofill_request_id_ = message_id_counter++;
+ Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
+ field_name, text,
+ node_id,
+ form_field_autofill_request_id_));
+}
+
+void RenderView::OnReceivedAutofillSuggestions(
+ int64 node_id,
+ int request_id,
+ const std::vector<std::wstring> suggestions,
+ int default_suggestion_index) {
+ if (!webview() || request_id != form_field_autofill_request_id_)
+ return;
+
+ webview()->AutofillSuggestionsForNode(node_id, suggestions,
+ default_suggestion_index);
+}
+
void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
const std::string& json_arguments,
std::string* json_retval) {
@@ -1762,9 +1788,11 @@ WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) {
return view->webview();
}
-WebWidget* RenderView::CreatePopupWidget(WebView* webview) {
+WebWidget* RenderView::CreatePopupWidget(WebView* webview,
+ bool focus_on_show) {
RenderWidget* widget = RenderWidget::Create(routing_id_,
- RenderThread::current());
+ RenderThread::current(),
+ focus_on_show);
return widget->webwidget();
}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index eee08e1..8484afd 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -127,6 +127,9 @@ class RenderView : public RenderWidget, public WebViewDelegate,
virtual bool RunBeforeUnloadConfirm(WebView* webview,
const std::wstring& message);
virtual void OnUnloadListenerChanged(WebView* webview, WebFrame* webframe);
+ virtual void QueryFormFieldAutofill(const std::wstring& field_name,
+ const std::wstring& text,
+ int64 node_id);
virtual void UpdateTargetURL(WebView* webview,
const GURL& url);
virtual void RunFileChooser(const std::wstring& default_filename,
@@ -197,7 +200,8 @@ class RenderView : public RenderWidget, public WebViewDelegate,
bool is_redirect);
virtual WebView* CreateWebView(WebView* webview, bool user_gesture);
- virtual WebWidget* CreatePopupWidget(WebView* webview);
+ virtual WebWidget* CreatePopupWidget(WebView* webview,
+ bool focus_on_show);
virtual WebPluginDelegate* CreatePluginDelegate(
WebView* webview,
const GURL& url,
@@ -457,6 +461,13 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// Notification about ui theme changes.
void OnThemeChanged();
+ // Notification that we have received autofill suggestion.
+ void OnReceivedAutofillSuggestions(
+ int64 node_id,
+ int request_id,
+ const std::vector<std::wstring> suggestions,
+ int default_suggestion_index);
+
#ifdef CHROME_PERSONALIZATION
void OnPersonalizationEvent(std::string event_name, std::string event_args);
#endif
@@ -673,6 +684,10 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// Set if we are waiting for an ack for ViewHostMsg_CreateWindow
bool waiting_for_create_window_ack_;
+ // The id of the last request sent for form field autofill. Used to ignore
+ // out of date responses.
+ int form_field_autofill_request_id_;
+
// A cached WebHistoryItem used for back/forward navigations initiated by
// WebCore (via the window.history.go API). We only have one such navigation
// pending at a time.
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 3cffb60f..ab1a270 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -69,7 +69,8 @@ DeferredCloses* DeferredCloses::current_ = NULL;
///////////////////////////////////////////////////////////////////////////////
-RenderWidget::RenderWidget(RenderThreadBase* render_thread)
+RenderWidget::RenderWidget(RenderThreadBase* render_thread,
+ bool focus_on_show)
: routing_id_(MSG_ROUTING_NONE),
opener_id_(MSG_ROUTING_NONE),
render_thread_(render_thread),
@@ -88,7 +89,8 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread)
ime_control_x_(-1),
ime_control_y_(-1),
ime_control_new_state_(false),
- ime_control_updated_(false) {
+ ime_control_updated_(false),
+ focus_on_show_(focus_on_show) {
RenderProcess::AddRefProcess();
DCHECK(render_thread_);
}
@@ -107,9 +109,11 @@ RenderWidget::~RenderWidget() {
/*static*/
RenderWidget* RenderWidget::Create(int32 opener_id,
- RenderThreadBase* render_thread) {
+ RenderThreadBase* render_thread,
+ bool focus_on_show) {
DCHECK(opener_id != MSG_ROUTING_NONE);
- scoped_refptr<RenderWidget> widget = new RenderWidget(render_thread);
+ scoped_refptr<RenderWidget> widget = new RenderWidget(render_thread,
+ focus_on_show);
widget->Init(opener_id); // adds reference
return widget;
}
@@ -125,7 +129,7 @@ void RenderWidget::Init(int32 opener_id) {
webwidget_.swap(&webwidget);
bool result = render_thread_->Send(
- new ViewHostMsg_CreateWidget(opener_id, &routing_id_));
+ new ViewHostMsg_CreateWidget(opener_id, focus_on_show_, &routing_id_));
if (result) {
render_thread_->AddRoute(routing_id_, this);
// Take a reference on behalf of the RenderThread. This will be balanced
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index 98d0377..f597dff 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -30,7 +30,9 @@ class RenderWidget : public IPC::Channel::Listener,
// Creates a new RenderWidget. The opener_id is the routing ID of the
// RenderView that this widget lives inside. The render_thread is any
// RenderThreadBase implementation, mostly commonly RenderThread::current().
- static RenderWidget* Create(int32 opener_id, RenderThreadBase* render_thread);
+ static RenderWidget* Create(int32 opener_id,
+ RenderThreadBase* render_thread,
+ bool focus_on_show);
// The routing ID assigned by the RenderProcess. Will be MSG_ROUTING_NONE if
// not yet assigned a view ID, in which case, the process MUST NOT send
@@ -86,7 +88,7 @@ class RenderWidget : public IPC::Channel::Listener,
// without ref-counting is an error.
friend class base::RefCounted<RenderWidget>;
- RenderWidget(RenderThreadBase* render_thread);
+ RenderWidget(RenderThreadBase* render_thread, bool focus_on_show);
virtual ~RenderWidget();
// Initializes this view with the given opener. CompleteInit must be called
@@ -261,6 +263,9 @@ class RenderWidget : public IPC::Channel::Listener,
bool ime_control_new_state_;
bool ime_control_updated_;
+ // Whether the window for this RenderWidget should be focused when shown.
+ bool focus_on_show_;
+
// Holds all the needed plugin window moves for a scroll.
std::vector<WebPluginGeometry> plugin_window_moves_;
diff --git a/chrome/renderer/render_widget_unittest.cc b/chrome/renderer/render_widget_unittest.cc
index 086f8bf..f280aa7 100644
--- a/chrome/renderer/render_widget_unittest.cc
+++ b/chrome/renderer/render_widget_unittest.cc
@@ -114,7 +114,9 @@ class MockRenderThread : public RenderThreadBase {
}
// The Widget expects to be returned valid route_id.
- void OnMsgCreateWidget(int opener_id, int* route_id) {
+ void OnMsgCreateWidget(int opener_id,
+ bool focus_on_show,
+ int* route_id) {
opener_id_ = opener_id;
*route_id = routing_id_;
}
@@ -141,7 +143,7 @@ TEST(RenderWidgetTest, CreateAndCloseWidget) {
{
scoped_refptr<RenderWidget> rw =
- RenderWidget::Create(kOpenerId, &render_thread);
+ RenderWidget::Create(kOpenerId, &render_thread, true);
ASSERT_TRUE(rw != NULL);
// After the RenderWidget it must have sent a message to the render thread
diff --git a/webkit/build/glue/glue.vcproj b/webkit/build/glue/glue.vcproj
index 879bf66..dcae341 100644
--- a/webkit/build/glue/glue.vcproj
+++ b/webkit/build/glue/glue.vcproj
@@ -381,6 +381,14 @@
>
</File>
<File
+ RelativePath="..\..\glue\form_autocomplete_listener.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\glue\form_autocomplete_listener.h"
+ >
+ </File>
+ <File
RelativePath="..\..\glue\glue_accessibility.cc"
>
</File>
diff --git a/webkit/build/port/port.vcproj b/webkit/build/port/port.vcproj
index 3a42435..b18530a 100644
--- a/webkit/build/port/port.vcproj
+++ b/webkit/build/port/port.vcproj
@@ -807,6 +807,10 @@
>
</File>
<File
+ RelativePath="..\..\port\platform\chromium\PopupMenuChromium.h"
+ >
+ </File>
+ <File
RelativePath="..\..\port\platform\chromium\SearchPopupMenuChromium.cpp"
>
</File>
diff --git a/webkit/glue/SConscript b/webkit/glue/SConscript
index c82a3c8..0870d6b 100644
--- a/webkit/glue/SConscript
+++ b/webkit/glue/SConscript
@@ -35,6 +35,7 @@ input_files = [
'editor_client_impl.cc',
'entity_map.cc',
'event_conversion.cc',
+ 'form_autocomplete_listener.cc',
'feed_preview.cc',
'glue_util.cc',
'glue_serialize.cc',
diff --git a/webkit/glue/autocomplete_input_listener.h b/webkit/glue/autocomplete_input_listener.h
index 3b92b86..fe412f1 100644
--- a/webkit/glue/autocomplete_input_listener.h
+++ b/webkit/glue/autocomplete_input_listener.h
@@ -16,7 +16,6 @@
MSVC_PUSH_WARNING_LEVEL(0);
#include "EventListener.h"
MSVC_POP_WARNING();
-#undef LOG
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
diff --git a/webkit/glue/chrome_client_impl.cc b/webkit/glue/chrome_client_impl.cc
index 387f307..081d4c7 100644
--- a/webkit/glue/chrome_client_impl.cc
+++ b/webkit/glue/chrome_client_impl.cc
@@ -449,12 +449,14 @@ void ChromeClientImpl::runFileChooser(const WebCore::String& default_path,
delegate->RunFileChooser(suggestion, chooser);
}
-void ChromeClientImpl::popupOpened(
- WebCore::FramelessScrollView* popup_view, const WebCore::IntRect& bounds) {
+void ChromeClientImpl::popupOpened(WebCore::FramelessScrollView* popup_view,
+ const WebCore::IntRect& bounds,
+ bool focus_on_show) {
WebViewDelegate* d = webview_->delegate();
if (d) {
WebWidgetImpl* webwidget =
- static_cast<WebWidgetImpl*>(d->CreatePopupWidget(webview_));
+ static_cast<WebWidgetImpl*>(d->CreatePopupWidget(webview_,
+ focus_on_show));
webwidget->Init(popup_view, webkit_glue::FromIntRect(bounds));
}
}
diff --git a/webkit/glue/chrome_client_impl.h b/webkit/glue/chrome_client_impl.h
index 88cf83c..7bb132b 100644
--- a/webkit/glue/chrome_client_impl.h
+++ b/webkit/glue/chrome_client_impl.h
@@ -115,7 +115,8 @@ public:
virtual void runFileChooser(const WebCore::String&,
PassRefPtr<WebCore::FileChooser>);
virtual void popupOpened(WebCore::FramelessScrollView* popup_view,
- const WebCore::IntRect& bounds);
+ const WebCore::IntRect& bounds,
+ bool focus_on_show);
void SetCursor(const WebCursor& cursor);
diff --git a/webkit/glue/form_autocomplete_listener.cc b/webkit/glue/form_autocomplete_listener.cc
new file mode 100644
index 0000000..aaaf0f70
--- /dev/null
+++ b/webkit/glue/form_autocomplete_listener.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-2008 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 "config.h"
+
+#include "webkit/glue/form_autocomplete_listener.h"
+
+MSVC_PUSH_WARNING_LEVEL(0);
+#include "HTMLInputElement.h"
+MSVC_POP_WARNING();
+
+#undef LOG
+
+#include "webkit/glue/autocomplete_input_listener.h"
+#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webview_delegate.h"
+
+namespace webkit_glue {
+
+FormAutocompleteListener::FormAutocompleteListener(
+ WebViewDelegate* webview_delegate,
+ WebCore::HTMLInputElement* input_element)
+ : AutocompleteInputListener(new HTMLInputDelegate(input_element)),
+ webview_delegate_(webview_delegate),
+ name_(webkit_glue::StringToStdWString(input_element->name().string())),
+ node_id_(reinterpret_cast<int64>(input_element)) {
+ DCHECK(input_element->isTextField() && !input_element->isPasswordField() &&
+ input_element->autoComplete());
+}
+
+void FormAutocompleteListener::OnInlineAutocompleteNeeded(
+ const std::wstring& user_input) {
+ webview_delegate_->QueryFormFieldAutofill(name_, user_input, node_id_);
+}
+
+} // namespace
diff --git a/webkit/glue/form_autocomplete_listener.h b/webkit/glue/form_autocomplete_listener.h
new file mode 100644
index 0000000..e55522e
--- /dev/null
+++ b/webkit/glue/form_autocomplete_listener.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2006-2008 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 WEBKIT_GLUE_FORM_AUTOCOMPLETE_LISTENER_
+#define WEBKIT_GLUE_FORM_AUTOCOMPLETE_LISTENER_
+
+#include <string>
+
+#include "webkit/glue/autocomplete_input_listener.h"
+
+class WebViewDelegate;
+
+namespace webkit_glue {
+
+// This class listens for the user typing in a text input in a form and queries
+// the browser for autofill information.
+
+class FormAutocompleteListener : public AutocompleteInputListener {
+ public:
+ FormAutocompleteListener(WebViewDelegate* webview_delegate,
+ WebCore::HTMLInputElement* input_element);
+ virtual ~FormAutocompleteListener() { }
+
+ // AutocompleteInputListener implementation.
+ virtual void OnBlur(const std::wstring& user_input) { }
+ virtual void OnInlineAutocompleteNeeded(const std::wstring& user_input);
+
+ private:
+ // The delegate associated with the WebView that contains thhe input we are
+ // listening to.
+ WebViewDelegate* webview_delegate_;
+
+ // The name of the input node we are listening to.
+ std::wstring name_;
+
+ // An id to represent the input element. That ID is passed to the call that
+ // queries for suggestions.
+ int64 node_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(FormAutocompleteListener);
+};
+
+} // webkit_glue
+
+#endif // WEBKIT_GLUE_FORM_AUTOCOMPLETE_LISTENER_
diff --git a/webkit/glue/password_autocomplete_listener.cc b/webkit/glue/password_autocomplete_listener.cc
index aaf6125..0a88ab3 100644
--- a/webkit/glue/password_autocomplete_listener.cc
+++ b/webkit/glue/password_autocomplete_listener.cc
@@ -6,6 +6,7 @@
// component.
#include "webkit/glue/password_autocomplete_listener.h"
+#undef LOG
#include "base/logging.h"
namespace webkit_glue {
diff --git a/webkit/glue/webframeloaderclient_impl.cc b/webkit/glue/webframeloaderclient_impl.cc
index 8138900..06e0645 100644
--- a/webkit/glue/webframeloaderclient_impl.cc
+++ b/webkit/glue/webframeloaderclient_impl.cc
@@ -16,6 +16,9 @@ MSVC_PUSH_WARNING_LEVEL(0);
#include "Element.h"
#include "HistoryItem.h"
#include "HTMLFormElement.h" // needed by FormState.h
+#include "HTMLFormControlElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
#include "FormState.h"
#include "FrameLoader.h"
#include "FrameLoadRequest.h"
@@ -39,8 +42,9 @@ MSVC_POP_WARNING();
#if defined(OS_WIN)
#include "webkit/activex_shim/activex_shared.h"
#endif
-#include "webkit/glue/webframeloaderclient_impl.h"
#include "webkit/glue/alt_404_page_resource_fetcher.h"
+#include "webkit/glue/autocomplete_input_listener.h"
+#include "webkit/glue/form_autocomplete_listener.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/password_form_dom_manager.h"
#include "webkit/glue/plugins/plugin_list.h"
@@ -48,6 +52,7 @@ MSVC_POP_WARNING();
#include "webkit/glue/webdatasource_impl.h"
#include "webkit/glue/webdocumentloader_impl.h"
#include "webkit/glue/weberror_impl.h"
+#include "webkit/glue/webframeloaderclient_impl.h"
#include "webkit/glue/webhistoryitem_impl.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin_impl.h"
@@ -351,10 +356,26 @@ void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() {
if (!form->autoComplete())
continue;
+ std::set<std::wstring> password_related_fields;
scoped_ptr<PasswordForm> data(
PasswordFormDomManager::CreatePasswordForm(form));
- if (data.get())
+ if (data.get()) {
actions.push_back(*data);
+ // Let's remember the names of password related fields so we do not
+ // autofill them with the regular form autofill.
+ DCHECK(!data->username_element.empty());
+ DCHECK(!data->password_element.empty());
+ password_related_fields.insert(data->username_element);
+ password_related_fields.insert(data->password_element);
+ if (!data->old_password_element.empty())
+ password_related_fields.insert(data->old_password_element);
+ }
+
+ // Now let's register for any text input.
+ // TODO(jcampan): bug #3847 merge password and form autofill so we
+ // traverse the form elements only once.
+ // Disabling the autofill to investigate the perf regression on build bot.
+ // RegisterAutofillListeners(form, password_related_fields);
}
}
@@ -686,6 +707,40 @@ NavigationGesture WebFrameLoaderClient::NavigationGestureForLastLoad() {
NavigationGestureAuto;
}
+void WebFrameLoaderClient::RegisterAutofillListeners(
+ WebCore::HTMLFormElement* form,
+ const std::set<std::wstring>& excluded_fields) {
+
+ WebViewDelegate* webview_delegate = webframe_->webview_impl()->delegate();
+ if (!webview_delegate)
+ return;
+
+ for (size_t i = 0; i < form->formElements.size(); i++) {
+ WebCore::HTMLFormControlElement* form_element = form->formElements[i];
+ if (!form_element->hasLocalName(WebCore::HTMLNames::inputTag))
+ continue;
+
+ WebCore::HTMLInputElement* input_element =
+ static_cast<WebCore::HTMLInputElement*>(form_element);
+ if (!input_element->isEnabled() || !input_element->isTextField() ||
+ input_element->isPasswordField() || !input_element->autoComplete()) {
+ continue;
+ }
+
+ std::wstring name = webkit_glue::StringToStdWString(input_element->name());
+ if (excluded_fields.find(name) != excluded_fields.end())
+ continue;
+
+#if !defined(OS_MACOSX)
+ // FIXME on Mac
+ webkit_glue::FormAutocompleteListener* listener =
+ new webkit_glue::FormAutocompleteListener(webview_delegate,
+ input_element);
+ webkit_glue::AttachForInlineAutocomplete(input_element, listener);
+#endif
+ }
+}
+
void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) {
WebViewImpl* webview = webframe_->webview_impl();
WebViewDelegate* d = webview->delegate();
@@ -1478,4 +1533,3 @@ bool WebFrameLoaderClient::ActionSpecifiesDisposition(
*disposition = shift ? NEW_WINDOW : SAVE_TO_DISK;
return true;
}
-
diff --git a/webkit/glue/webframeloaderclient_impl.h b/webkit/glue/webframeloaderclient_impl.h
index 20b12ee..6010ba8 100644
--- a/webkit/glue/webframeloaderclient_impl.h
+++ b/webkit/glue/webframeloaderclient_impl.h
@@ -5,6 +5,8 @@
#ifndef WEBKIT_GLUE_WEBFRAMELOADERCLIENT_IMPL_H__
#define WEBKIT_GLUE_WEBFRAMELOADERCLIENT_IMPL_H__
+#include <set>
+
#include "base/compiler_specific.h"
MSVC_PUSH_WARNING_LEVEL(0);
@@ -18,6 +20,7 @@ MSVC_POP_WARNING();
namespace WebCore {
class Frame;
+class HTMLFormElement;
class Widget;
}
@@ -209,6 +212,11 @@ class WebFrameLoaderClient : public WebCore::FrameLoaderClient {
// otherwise returns NavigationGestureUnknown.
NavigationGesture NavigationGestureForLastLoad();
+ // Registers the text input fields in the passed form for autofill, with the
+ // exclusion of any field whose name is contained in |excluded_fields|.
+ void RegisterAutofillListeners(WebCore::HTMLFormElement* form,
+ const std::set<std::wstring>& excluded_fields);
+
// The WebFrame that owns this object and manages its lifetime. Therefore,
// the web frame object is guaranteed to exist.
WebFrameImpl* webframe_;
diff --git a/webkit/glue/webplugin_impl_mac.mm b/webkit/glue/webplugin_impl_mac.mm
index 191ebb7..1a420ea 100644
--- a/webkit/glue/webplugin_impl_mac.mm
+++ b/webkit/glue/webplugin_impl_mac.mm
@@ -4,6 +4,9 @@
#include "config.h"
+#include "wtf/ASCIICType.h"
+
+#undef LOG
#include "webkit/glue/webplugin_impl.h"
// TODO(pinkerton): all of this needs to be filled in. webplugin_impl.cc has
diff --git a/webkit/glue/webview.h b/webkit/glue/webview.h
index e47ad0e..1c67c4f4 100644
--- a/webkit/glue/webview.h
+++ b/webkit/glue/webview.h
@@ -6,6 +6,7 @@
#define WEBKIT_GLUE_WEBVIEW_H__
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/ref_counted.h"
@@ -195,6 +196,12 @@ class WebView : public WebWidget {
virtual void DragTargetDrop(
int client_x, int client_y, int screen_x, int screen_y) = 0;
+ // Notifies the webview that autofill suggestions are available for a node.
+ virtual void AutofillSuggestionsForNode(
+ int64 node_id,
+ const std::vector<std::wstring>& suggestions,
+ int default_suggestion_index) = 0;
+
private:
DISALLOW_EVIL_CONSTRUCTORS(WebView);
};
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index 97944dd..1ce50c5 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -108,7 +108,8 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
// This method is called to create a new WebWidget to act as a popup
// (like a drop-down menu).
- virtual WebWidget* CreatePopupWidget(WebView* webview) {
+ virtual WebWidget* CreatePopupWidget(WebView* webview,
+ bool focus_on_show) {
return NULL;
}
@@ -457,6 +458,14 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
virtual void OnUnloadListenerChanged(WebView* webview, WebFrame* webframe) {
}
+ // Queries the browser for suggestions to be shown for the form text field
+ // named |field_name|. |text| is the text entered by the user so far and
+ // |node_id| is the id of the node of the input field.
+ virtual void QueryFormFieldAutofill(const std::wstring& field_name,
+ const std::wstring& text,
+ int64 node_id) {
+ }
+
// UIDelegate --------------------------------------------------------------
// Asks the browser to show a modal HTML dialog. The dialog is passed the
diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc
index 6375fa3..c807b31 100644
--- a/webkit/glue/webview_impl.cc
+++ b/webkit/glue/webview_impl.cc
@@ -35,6 +35,7 @@
#include "base/compiler_specific.h"
MSVC_PUSH_WARNING_LEVEL(0);
+#include "CSSStyleSelector.h"
#if defined(OS_WIN)
#include "Cursor.h"
#endif
@@ -50,20 +51,25 @@ MSVC_PUSH_WARNING_LEVEL(0);
#include "FrameTree.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "HTMLNames.h"
+#include "HTMLInputElement.h"
#include "HitTestResult.h"
#include "Image.h"
#include "InspectorController.h"
#include "IntRect.h"
#include "KeyboardEvent.h"
#include "MIMETypeRegistry.h"
+#include "NodeRenderStyle.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginInfoStore.h"
+#include "PopupMenuClient.h"
#if defined(OS_WIN)
#include "RenderThemeWin.h"
#endif
+#include "RenderView.h"
#include "ResourceHandle.h"
#include "SelectionController.h"
#include "Settings.h"
@@ -94,6 +100,7 @@ MSVC_POP_WARNING();
#include "webkit/glue/webview_delegate.h"
#include "webkit/glue/webview_impl.h"
#include "webkit/glue/webwidget_impl.h"
+#include "webkit/port/platform/chromium/PopupMenuChromium.h"
#include "webkit/port/platform/graphics/PlatformContextSkia.h"
// Get rid of WTF's pow define so we can use std::pow.
@@ -115,6 +122,126 @@ static const double kMaxTextSizeMultiplier = 3.0;
static const WebCore::DragOperation kDropTargetOperation =
static_cast<WebCore::DragOperation>(DragOperationCopy | DragOperationLink);
+// AutocompletePopupMenuClient
+class AutocompletePopupMenuClient
+ : public RefCounted<AutocompletePopupMenuClient>,
+ public WebCore::PopupMenuClient {
+ public:
+ AutocompletePopupMenuClient(WebViewImpl* webview,
+ WebCore::HTMLInputElement* text_field,
+ const std::vector<std::wstring>& suggestions,
+ int default_suggestion_index)
+ : text_field_(text_field),
+ selected_index_(default_suggestion_index),
+ webview_(webview) {
+ for (std::vector<std::wstring>::const_iterator iter = suggestions.begin();
+ iter != suggestions.end(); ++iter) {
+ suggestions_.push_back(webkit_glue::StdWStringToString(*iter));
+ }
+ }
+ virtual ~AutocompletePopupMenuClient() {
+ }
+
+ virtual void valueChanged(unsigned listIndex, bool fireEvents = true) {
+ text_field_->setValue(suggestions_[listIndex]);
+ }
+
+ virtual WebCore::String itemText(unsigned list_index) const {
+ return suggestions_[list_index];
+ }
+
+ virtual bool itemIsEnabled(unsigned listIndex) const {
+ return true;
+ }
+
+ virtual PopupMenuStyle itemStyle(unsigned listIndex) const {
+ return menuStyle();
+ }
+
+ virtual PopupMenuStyle menuStyle() const {
+ RenderStyle* style = text_field_->renderStyle() ?
+ text_field_->renderStyle() :
+ text_field_->computedStyle();
+ return PopupMenuStyle(style->color(), Color::white, style->font(),
+ style->visibility() == VISIBLE);
+ }
+
+ virtual int clientInsetLeft() const {
+ return 0;
+ }
+ virtual int clientInsetRight() const {
+ return 0;
+ }
+ virtual int clientPaddingLeft() const {
+#if defined(OS_WIN)
+ return theme()->popupInternalPaddingLeft(text_field_->computedStyle());
+#else
+ NOTIMPLEMENTED();
+ return 0;
+#endif
+ }
+ virtual int clientPaddingRight() const {
+#if defined(OS_WIN)
+ return theme()->popupInternalPaddingRight(text_field_->computedStyle());
+#else
+ NOTIMPLEMENTED();
+ return 0;
+#endif
+ }
+ virtual int listSize() const {
+ return suggestions_.size();
+ }
+ virtual int selectedIndex() const {
+ return selected_index_;
+ }
+ virtual void hidePopup() {
+ webview_->HideAutoCompletePopup();
+ }
+ virtual bool itemIsSeparator(unsigned listIndex) const {
+ return false;
+ }
+ virtual bool itemIsLabel(unsigned listIndex) const {
+ return false;
+ }
+ virtual bool itemIsSelected(unsigned listIndex) const {
+ return false;
+ }
+ virtual bool shouldPopOver() const {
+ return false;
+ }
+ virtual bool valueShouldChangeOnHotTrack() const {
+ return false;
+ }
+
+ virtual FontSelector* fontSelector() const {
+ return text_field_->document()->styleSelector()->fontSelector();
+ }
+
+ virtual void setTextFromItem(unsigned listIndex) {
+ text_field_->setValue(suggestions_[listIndex]);
+ }
+
+ virtual HostWindow* hostWindow() const {
+ return text_field_->document()->view()->hostWindow();
+ }
+
+ virtual PassRefPtr<Scrollbar> createScrollbar(
+ ScrollbarClient* client,
+ ScrollbarOrientation orientation,
+ ScrollbarControlSize size) {
+ RefPtr<Scrollbar> widget = Scrollbar::createNativeScrollbar(client,
+ orientation,
+ size);
+ return widget.release();
+ }
+
+ private:
+ RefPtr<WebCore::HTMLInputElement> text_field_;
+ std::vector<WebCore::String> suggestions_;
+ int selected_index_;
+ WebViewImpl* webview_;
+};
+
// WebView ----------------------------------------------------------------
/*static*/
@@ -292,6 +419,18 @@ bool WebViewImpl::KeyEvent(const WebKeyboardEvent& event) {
// event.
suppress_next_keypress_event_ = false;
+ // Give autocomplete a chance to consume the key events it is interested in.
+ if (autocomplete_popup_ &&
+ autocomplete_popup_->isInterestedInEventForKey(event.key_code)) {
+ if (autocomplete_popup_->handleKeyEvent(MakePlatformKeyboardEvent(event)))
+ return true;
+ return false;
+ }
+
+ // A new key being pressed should hide the popup.
+ if (event.type == WebInputEvent::KEY_DOWN)
+ HideAutoCompletePopup();
+
Frame* frame = GetFocusedWebCoreFrame();
if (!frame)
return false;
@@ -714,7 +853,6 @@ bool WebViewImpl::HandleInputEvent(const WebInputEvent* input_event) {
// we're done.
if (doing_drag_and_drop_)
return true;
-
// TODO(eseidel): Remove g_current_input_event.
// This only exists to allow ChromeClient::show() to know which mouse button
// triggered a window.open event.
@@ -782,6 +920,14 @@ void WebViewImpl::SetBackForwardListSize(int size) {
void WebViewImpl::SetFocus(bool enable) {
if (enable) {
+ // Hide the popup menu if any.
+ // TODO(jcampan): bug #3844: we should do that when we lose focus. The
+ // reason we are not doing it is because when clicking on the autofill
+ // popup, the page first loses focus before the mouse click is sent to the
+ // popup. So if we close when the focus is lost, the mouse click does not
+ // do anything.
+ HideAutoCompletePopup();
+
// Getting the focused frame will have the side-effect of setting the main
// frame as the focused frame if it is not already focused. Otherwise, if
// there is already a focused frame, then this does nothing.
@@ -803,8 +949,6 @@ void WebViewImpl::SetFocus(bool enable) {
// updated below.
ReleaseFocusReferences();
- // Clear focus on the currently focused frame if any.
-
if (!main_frame_)
return;
@@ -1018,7 +1162,8 @@ void WebViewImpl::SetInitialFocus(bool reverse) {
// We have to set the key type explicitly to avoid an assert in the
// KeyboardEvent constructor.
platform_event.SetKeyType(PlatformKeyboardEvent::RawKeyDown);
- RefPtr<KeyboardEvent> webkit_event = KeyboardEvent::create(platform_event, NULL);
+ RefPtr<KeyboardEvent> webkit_event = KeyboardEvent::create(platform_event,
+ NULL);
page()->focusController()->setInitialFocus(
reverse ? WebCore::FocusDirectionBackward :
WebCore::FocusDirectionForward,
@@ -1331,6 +1476,59 @@ SearchableFormData* WebViewImpl::CreateSearchableFormDataForFocusedNode() {
return NULL;
}
+void WebViewImpl::AutofillSuggestionsForNode(
+ int64 node_id,
+ const std::vector<std::wstring>& suggestions,
+ int default_suggestion_index) {
+ if (!main_frame_ || suggestions.empty())
+ return;
+
+ DCHECK(default_suggestion_index < static_cast<int>(suggestions.size()));
+
+ Frame* frame = main_frame_->frame();
+ if (!frame)
+ return;
+
+ if (RefPtr<Frame> focused =
+ frame->page()->focusController()->focusedFrame()) {
+ RefPtr<Document> document = focused->document();
+ if (!document.get())
+ return;
+
+ RefPtr<Node> focused_node = document->focusedNode();
+ // If the node for which we queried the autofill suggestions is not the
+ // focused node, then we have nothing to do.
+ // TODO(jcampan): also check the carret is at the end and that the text has
+ // not changed.
+ if (!focused_node.get() ||
+ reinterpret_cast<int64>(focused_node.get()) != node_id)
+ return;
+
+ if (!focused_node->hasTagName(WebCore::HTMLNames::inputTag)) {
+ NOTREACHED();
+ return;
+ }
+
+ WebCore::HTMLInputElement* input_elem =
+ static_cast<WebCore::HTMLInputElement*>(focused_node.get());
+ // Hide any current autocomplete popup.
+ HideAutoCompletePopup();
+
+ if (suggestions.size() > 0) {
+ autocomplete_popup_client_ =
+ adoptRef(new AutocompletePopupMenuClient(this, input_elem,
+ suggestions,
+ default_suggestion_index));
+ // Autocomplete popup does not get focused. We need the page to still
+ // have focus so the user can keep typing when the popup is showing.
+ autocomplete_popup_ =
+ WebCore::PopupContainer::create(autocomplete_popup_client_.get(),
+ false);
+ autocomplete_popup_->show(focused_node->getRect(), frame->view(), 0);
+ }
+ }
+}
+
void WebViewImpl::DidCommitLoad(bool* is_new_navigation) {
if (is_new_navigation)
*is_new_navigation = observed_new_navigation_;
@@ -1479,3 +1677,11 @@ void WebViewImpl::DeleteImageResourceFetcher(ImageResourceFetcher* fetcher) {
// deletion.
MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
}
+
+void WebViewImpl::HideAutoCompletePopup() {
+ if (autocomplete_popup_) {
+ autocomplete_popup_->hidePopup();
+ autocomplete_popup_.clear();
+ autocomplete_popup_client_.clear();
+ }
+}
diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h
index da0d533..83cddebd 100644
--- a/webkit/glue/webview_impl.h
+++ b/webkit/glue/webview_impl.h
@@ -27,10 +27,12 @@ class HistoryItem;
class KeyboardEvent;
class Page;
class PlatformKeyboardEvent;
+class PopupContainer;
class Range;
class Widget;
}
+class AutocompletePopupMenuClient;
class ImageResourceFetcher;
class SearchableFormData;
struct WebDropData;
@@ -98,6 +100,10 @@ class WebViewImpl : public WebView, public WebCore::BackForwardListClient {
virtual void DragTargetDragLeave();
virtual void DragTargetDrop(
int client_x, int client_y, int screen_x, int screen_y);
+ virtual void AutofillSuggestionsForNode(
+ int64 node_id,
+ const std::vector<std::wstring>& suggestions,
+ int default_suggestion_index);
// WebViewImpl
@@ -178,6 +184,9 @@ class WebViewImpl : public WebView, public WebCore::BackForwardListClient {
bool errored,
const SkBitmap& image);
+ // Hides the autocomplete popup if it is showing.
+ void HideAutoCompletePopup();
+
protected:
friend class WebView; // So WebView::Create can call our constructor
@@ -287,6 +296,13 @@ class WebViewImpl : public WebView, public WebCore::BackForwardListClient {
// Represents whether or not this object should process incoming IME events.
bool ime_accept_events_;
+ // The currently shown autocomplete popup.
+ RefPtr<WebCore::PopupContainer> autocomplete_popup_;
+
+ // The popup client of the currently shown autocomplete popup. Necessary for
+ // managing the life of the client.
+ RefPtr<AutocompletePopupMenuClient> autocomplete_popup_client_;
+
// HACK: current_input_event is for ChromeClientImpl::show(), until we can fix
// WebKit to pass enough information up into ChromeClient::show() so we can
// decide if the window.open event was caused by a middle-mouse click
diff --git a/webkit/port/page/chromium/ChromeClientChromium.h b/webkit/port/page/chromium/ChromeClientChromium.h
index 5813770..783b5b5 100644
--- a/webkit/port/page/chromium/ChromeClientChromium.h
+++ b/webkit/port/page/chromium/ChromeClientChromium.h
@@ -26,7 +26,7 @@ namespace WebCore {
// Notifies the client of a new popup widget. The client should place
// and size the widget with the given bounds, relative to the screen.
- virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds) = 0;
+ virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds, bool focus_on_show) = 0;
};
}
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.cpp b/webkit/port/platform/chromium/PopupMenuChromium.cpp
index d30df68..ae9f164 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.cpp
+++ b/webkit/port/platform/chromium/PopupMenuChromium.cpp
@@ -36,9 +36,9 @@
#include "ChromeClientChromium.h"
#include "Document.h"
#include "Font.h"
-#include "Frame.h"
#include "FrameView.h"
#include "FontSelector.h"
+#include "Frame.h"
#include "FramelessScrollView.h"
#include "FramelessScrollViewClient.h"
#include "GraphicsContext.h"
@@ -57,6 +57,8 @@
#include "Widget.h"
#pragma warning(pop)
+#include "webkit/port/platform/chromium/PopupMenuChromium.h"
+
using namespace WTF;
using namespace Unicode;
@@ -72,51 +74,6 @@ static const int kMaxHeight = 500;
static const int kBorderSize = 1;
static const TimeStamp kTypeAheadTimeoutMs = 1000;
-class PopupListBox;
-
-// TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
-
-// This class holds a PopupListBox. Its sole purpose is to be able to draw
-// a border around its child. All its paint/event handling is just forwarded
-// to the child listBox (with the appropriate transforms).
-class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
-public:
- static PassRefPtr<PopupContainer> create(PopupMenuClient* client);
-
- // FramelessScrollView
- virtual void paint(GraphicsContext* gc, const IntRect& rect);
- virtual void hide();
- virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
- virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
- virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
- virtual bool handleWheelEvent(const PlatformWheelEvent& event);
- virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
-
- // PopupContainer methods
-
- // Show the popup
- void showPopup(FrameView* view);
-
- // Hide the popup. Do not call this directly: use client->hidePopup().
- void hidePopup();
-
- // Compute size of widget and children.
- void layout();
-
- PopupListBox* listBox() const { return m_listBox.get(); }
-
-private:
- friend class RefCounted<PopupContainer>;
-
- PopupContainer(PopupMenuClient* client);
- ~PopupContainer();
-
- // Paint the border.
- void paintBorder(GraphicsContext* gc, const IntRect& rect);
-
- RefPtr<PopupListBox> m_listBox;
-};
-
// This class uses WebCore code to paint and handle events for a drop-down list
// box ("combobox" on Windows).
class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {
@@ -170,6 +127,9 @@ public:
// Compute size of widget and children.
void layout();
+ // Returns whether the popup wants to process events for the passed key.
+ bool isInterestedInEventForKey(int key_code);
+
private:
friend class PopupContainer;
friend class RefCounted<PopupListBox>;
@@ -327,13 +287,15 @@ static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent&
// PopupContainer implementation
// static
-PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client)
+PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,
+ bool focusOnShow)
{
- return adoptRef(new PopupContainer(client));
+ return adoptRef(new PopupContainer(client, focusOnShow));
}
-PopupContainer::PopupContainer(PopupMenuClient* client)
- : m_listBox(new PopupListBox(client))
+PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow)
+ : m_listBox(new PopupListBox(client)),
+ m_focusOnShow(focusOnShow)
{
// FrameViews are created with a refcount of 1 so it needs releasing after we
// assign it to a RefPtr.
@@ -367,7 +329,7 @@ void PopupContainer::showPopup(FrameView* view)
if (widgetRect.bottom() > static_cast<int>(screen.bottom()))
widgetRect.move(0, -(widgetRect.height() + selectHeight));
- chromeClient->popupOpened(this, widgetRect);
+ chromeClient->popupOpened(this, widgetRect, m_focusOnShow);
}
// Must get called after we have a client and containingWindow.
@@ -474,6 +436,33 @@ void PopupContainer::paintBorder(GraphicsContext* gc, const IntRect& rect)
gc->drawRect(IntRect(tx + width() - kBorderSize, ty, kBorderSize, height()));
}
+bool PopupContainer::isInterestedInEventForKey(int key_code) {
+ return m_listBox->isInterestedInEventForKey(key_code);
+}
+
+void PopupContainer::show(const IntRect& r, FrameView* v, int index) {
+ // The rect is the size of the select box. It's usually larger than we need.
+ // subtract border size so that usually the container will be displayed
+ // exactly the same width as the select box.
+ listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
+
+ listBox()->updateFromElement();
+
+ // We set the selected item in updateFromElement(), and disregard the
+ // index passed into this function (same as Webkit's PopupMenuWin.cpp)
+ // TODO(ericroman): make sure this is correct, and add an assertion.
+ // DCHECK(popupWindow(popup)->listBox()->selectedIndex() == index);
+
+ // Convert point to main window coords.
+ IntPoint location = v->contentsToWindow(r.location());
+
+ // Move it below the select widget.
+ location.move(0, r.height());
+
+ IntRect popupRect(location, r.size());
+ setFrameRect(popupRect);
+ showPopup(v);
+}
///////////////////////////////////////////////////////////////////////////////
// PopupListBox implementation
@@ -548,6 +537,23 @@ bool PopupListBox::handleWheelEvent(const PlatformWheelEvent& event)
return true;
}
+// Should be kept in sync with handleKeyEvent().
+bool PopupListBox::isInterestedInEventForKey(int key_code) {
+ switch (key_code) {
+ case VKEY_ESCAPE:
+ case VKEY_RETURN:
+ case VKEY_UP:
+ case VKEY_DOWN:
+ case VKEY_PRIOR:
+ case VKEY_NEXT:
+ case VKEY_HOME:
+ case VKEY_END:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
{
if (event.type() == PlatformKeyboardEvent::KeyUp)
@@ -1036,29 +1042,8 @@ PopupMenu::~PopupMenu()
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
- p.m_popup = PopupContainer::create(client());
-
- // The rect is the size of the select box. It's usually larger than we need.
- // subtract border size so that usually the container will be displayed
- // exactly the same width as the select box.
- p.m_popup->listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
-
- updateFromElement();
-
- // We set the selected item in updateFromElement(), and disregard the
- // index passed into this function (same as Webkit's PopupMenuWin.cpp)
- // TODO(ericroman): make sure this is correct, and add an assertion.
- // DCHECK(popupWindow(m_popup)->listBox()->selectedIndex() == index);
-
- // Convert point to main window coords.
- IntPoint location = v->contentsToWindow(r.location());
-
- // Move it below the select widget.
- location.move(0, r.height());
-
- IntRect popupRect(location, r.size());
- p.m_popup->setFrameRect(popupRect);
- p.m_popup->showPopup(v);
+ p.m_popup = PopupContainer::create(client(), true);
+ p.m_popup->show(r, v, index);
}
void PopupMenu::hide()
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.h b/webkit/port/platform/chromium/PopupMenuChromium.h
index e69de29..d419468 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.h
+++ b/webkit/port/platform/chromium/PopupMenuChromium.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2006-2008 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 PopupMenuChromium_h
+#define PopupMenuChromium_h
+
+#pragma warning(push, 0)
+#include "PopupMenuClient.h"
+
+#include "FramelessScrollView.h"
+#include "IntRect.h"
+#pragma warning(pop)
+
+
+namespace WebCore {
+
+class PopupListBox;
+
+// TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
+
+// This class holds a PopupListBox (see cpp file). Its sole purpose is to be
+// able to draw a border around its child. All its paint/event handling is just
+// forwarded to the child listBox (with the appropriate transforms).
+// NOTE: this class is exposed so it can be instantiated direcly for the
+// autofill popup. We cannot use the Popup class directly in that case as the
+// autofill popup should not be focused when shown and we want to forward the
+// key events to it (through handleKeyEvent).
+
+class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
+public:
+ static PassRefPtr<PopupContainer> create(PopupMenuClient* client,
+ bool focusOnShow);
+
+ // Whether a key event should be sent to this popup.
+ virtual bool isInterestedInEventForKey(int key_code);
+
+ // FramelessScrollView
+ virtual void paint(GraphicsContext* gc, const IntRect& rect);
+ virtual void hide();
+ virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
+ virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
+ virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
+ virtual bool handleWheelEvent(const PlatformWheelEvent& event);
+ virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
+
+ // PopupContainer methods
+
+ // Show the popup
+ void showPopup(FrameView* view);
+
+ // Show the popup in the specified rect for the specified frame.
+ // Note: this code was somehow arbitrarily factored-out of the Popup class
+ // so WebViewImpl can create a PopupContainer.
+ void show(const IntRect& r, FrameView* v, int index);
+
+ // Hide the popup. Do not call this directly: use client->hidePopup().
+ void hidePopup();
+
+ // Compute size of widget and children.
+ void layout();
+
+ PopupListBox* listBox() const { return m_listBox.get(); }
+
+private:
+ friend class WTF::RefCounted<PopupContainer>;
+
+ PopupContainer(PopupMenuClient* client, bool focusOnShow);
+ ~PopupContainer();
+
+ // Paint the border.
+ void paintBorder(GraphicsContext* gc, const IntRect& rect);
+
+ RefPtr<PopupListBox> m_listBox;
+
+ // Whether the window showing this popup should be focused when shown.
+ bool m_focusOnShow;
+};
+
+}
+
+#endif // PopupMenuChromium_h
diff --git a/webkit/webkit.xcodeproj/project.pbxproj b/webkit/webkit.xcodeproj/project.pbxproj
index 990ba1b..77e4813 100644
--- a/webkit/webkit.xcodeproj/project.pbxproj
+++ b/webkit/webkit.xcodeproj/project.pbxproj
@@ -61,6 +61,7 @@
4D16381F0EBFA4FB008F024E /* StorageArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D1638060EBFA4FB008F024E /* StorageArea.cpp */; };
4D1638200EBFA4FC008F024E /* StorageEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D1638080EBFA4FB008F024E /* StorageEvent.cpp */; };
4D1638210EBFA4FC008F024E /* StorageMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D16380A0EBFA4FB008F024E /* StorageMap.cpp */; };
+ 4D163E990EC23D9D008F024E /* form_autocomplete_listener.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D163E970EC23D9D008F024E /* form_autocomplete_listener.cc */; };
4D2A63EB0EBBBEDF00B55603 /* MediaPlayerPrivateChromium.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2A63E90EBBBEDF00B55603 /* MediaPlayerPrivateChromium.cpp */; };
4D2A64400EBBC0A700B55603 /* V8HTMLVideoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2A643A0EBBC0A700B55603 /* V8HTMLVideoElement.cpp */; };
4D2A64410EBBC0A700B55603 /* V8MediaError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2A643C0EBBC0A700B55603 /* V8MediaError.cpp */; };
@@ -1483,6 +1484,9 @@
4D1638090EBFA4FB008F024E /* StorageEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageEvent.h; sourceTree = "<group>"; };
4D16380A0EBFA4FB008F024E /* StorageMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageMap.cpp; sourceTree = "<group>"; };
4D16380B0EBFA4FB008F024E /* StorageMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageMap.h; sourceTree = "<group>"; };
+ 4D163E970EC23D9D008F024E /* form_autocomplete_listener.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = form_autocomplete_listener.cc; sourceTree = "<group>"; };
+ 4D163E980EC23D9D008F024E /* form_autocomplete_listener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = form_autocomplete_listener.h; sourceTree = "<group>"; };
+ 4D163E9D0EC23DC6008F024E /* PopupMenuChromium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupMenuChromium.h; sourceTree = "<group>"; };
4D2A63E90EBBBEDF00B55603 /* MediaPlayerPrivateChromium.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaPlayerPrivateChromium.cpp; sourceTree = "<group>"; };
4D2A63EA0EBBBEDF00B55603 /* MediaPlayerPrivateChromium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerPrivateChromium.h; sourceTree = "<group>"; };
4D2A643A0EBBC0A700B55603 /* V8HTMLVideoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = V8HTMLVideoElement.cpp; sourceTree = "<group>"; };
@@ -7443,6 +7447,8 @@
8254050F0D92E3DA0006B936 /* feed_preview.cc */,
825405100D92E3DA0006B936 /* feed_preview.h */,
825405110D92E3DA0006B936 /* find_in_page_request.h */,
+ 4D163E970EC23D9D008F024E /* form_autocomplete_listener.cc */,
+ 4D163E980EC23D9D008F024E /* form_autocomplete_listener.h */,
825405120D92E3DA0006B936 /* form_data.h */,
825405140D92E3DA0006B936 /* glue_serialize.cc */,
825405150D92E3DA0006B936 /* glue_serialize.h */,
@@ -7782,6 +7788,7 @@
E473F6520EAE002F006C2098 /* PlatformCursor.h */,
E473F65D0EAE009A006C2098 /* PlatformWidget.h */,
E473F65E0EAE00A6006C2098 /* PopupMenuChromium.cpp */,
+ 4D163E9D0EC23DC6008F024E /* PopupMenuChromium.h */,
E473F65F0EAE00A6006C2098 /* PopupMenuPrivate.h */,
E473F6630EAE00E4006C2098 /* SearchPopupMenuChromium.cpp */,
E473F6650EAE00F4006C2098 /* SharedTimerChromium.cpp */,
@@ -9261,6 +9268,7 @@
E45626FE0E268F03005E4685 /* editor_client_impl.cc in Sources */,
E456270A0E268F03005E4685 /* event_conversion.cc in Sources */,
E45628370E269DBB005E4685 /* feed_preview.cc in Sources */,
+ 4D163E990EC23D9D008F024E /* form_autocomplete_listener.cc in Sources */,
E45626FA0E268F03005E4685 /* glue_serialize.cc in Sources */,
E45626F50E268F03005E4685 /* glue_util.cc in Sources */,
E4A238C70E3FA19C002BDE14 /* image_decoder.cc in Sources */,