summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 22:28:17 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 22:28:17 +0000
commit4d2b6fb574d019dab4080b3713d3d5e5aa0a91bd (patch)
treee384f04d2a7bc8403cf19929d84447782d6c7871
parente08a579d8d6701fa48eac6945248855bbb5a70a6 (diff)
downloadchromium_src-4d2b6fb574d019dab4080b3713d3d5e5aa0a91bd.zip
chromium_src-4d2b6fb574d019dab4080b3713d3d5e5aa0a91bd.tar.gz
chromium_src-4d2b6fb574d019dab4080b3713d3d5e5aa0a91bd.tar.bz2
Pressing the Del key while a item is selected in the autocomplete popup deletes that suggestion from the DB.
BUG=6176 TEST=Bring up the autofill popup in a form. Select an item and press the Del key. The item should be removed from the popup and should not show on subsequent autofill popups. Review URL: http://codereview.chromium.org/42258 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12221 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autofill_manager.cc12
-rw-r--r--chrome/browser/autofill_manager.h3
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc7
-rw-r--r--chrome/browser/renderer_host/render_view_host.h2
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h5
-rw-r--r--chrome/browser/tab_contents/web_contents.cc5
-rw-r--r--chrome/browser/tab_contents/web_contents.h2
-rw-r--r--chrome/browser/webdata/web_data_service.cc24
-rw-r--r--chrome/browser/webdata/web_data_service.h4
-rw-r--r--chrome/browser/webdata/web_database.cc26
-rw-r--r--chrome/browser/webdata/web_database.h5
-rw-r--r--chrome/common/render_messages_internal.h6
-rw-r--r--chrome/renderer/render_view.cc5
-rw-r--r--chrome/renderer/render_view.h2
-rw-r--r--webkit/glue/webview_delegate.h5
-rw-r--r--webkit/glue/webview_impl.cc59
-rw-r--r--webkit/glue/webview_impl.h5
17 files changed, 163 insertions, 14 deletions
diff --git a/chrome/browser/autofill_manager.cc b/chrome/browser/autofill_manager.cc
index 8025cbb..5cf318f 100644
--- a/chrome/browser/autofill_manager.cc
+++ b/chrome/browser/autofill_manager.cc
@@ -74,6 +74,18 @@ void AutofillManager::FetchValuesForName(const std::wstring& name,
GetFormValuesForElementName(name, prefix, limit, this);
}
+void AutofillManager::RemoveValueForName(const std::wstring& name,
+ const std::wstring& value) {
+ WebDataService* web_data_service =
+ profile()->GetWebDataService(Profile::EXPLICIT_ACCESS);
+ if (!web_data_service) {
+ NOTREACHED();
+ return;
+ }
+
+ web_data_service->RemoveFormValueForElementName(name, value);
+}
+
void AutofillManager::OnWebDataServiceRequestDone(WebDataService::Handle h,
const WDTypedResult* result) {
DCHECK(pending_query_handle_);
diff --git a/chrome/browser/autofill_manager.h b/chrome/browser/autofill_manager.h
index b3f03f9..bac2167 100644
--- a/chrome/browser/autofill_manager.h
+++ b/chrome/browser/autofill_manager.h
@@ -38,6 +38,9 @@ class AutofillManager : public WebDataServiceConsumer {
int64 node_id,
int request_id);
+ // Removes the specified name/value pair from the database.
+ void RemoveValueForName(const std::wstring& name, const std::wstring& value);
+
// WebDataServiceConsumer implementation.
virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
const WDTypedResult* result);
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 39f0648..6a4160e 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -760,6 +760,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
OnUnloadListenerChanged);
IPC_MESSAGE_HANDLER(ViewHostMsg_QueryFormFieldAutofill,
OnQueryFormFieldAutofill)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_RemoveAutofillEntry,
+ OnRemoveAutofillEntry)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFeedList, OnMsgUpdateFeedList)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg))
@@ -1290,6 +1292,11 @@ void RenderViewHost::OnQueryFormFieldAutofill(const std::wstring& field_name,
delegate_->GetAutofillSuggestions(field_name, user_text, node_id, request_id);
}
+void RenderViewHost::OnRemoveAutofillEntry(const std::wstring& field_name,
+ const std::wstring& value) {
+ delegate_->RemoveAutofillEntry(field_name, value);
+}
+
void RenderViewHost::AutofillSuggestionsReturned(
const std::vector<std::wstring>& suggestions,
int64 node_id, int request_id, int default_suggestion_index) {
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 92599ba..31e5315 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -546,6 +546,8 @@ class RenderViewHost : public RenderWidgetHost {
const std::wstring& user_text,
int64 node_id,
int request_id);
+ void OnRemoveAutofillEntry(const std::wstring& field_name,
+ const std::wstring& value);
// Helper function to send a navigation message. If a cross-site request is
// in progress, we may be suspended while waiting for the onbeforeunload
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 902c33f..1c10c62 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -320,6 +320,11 @@ class RenderViewHostDelegate {
int64 node_id,
int request_id) { }
+ // Called when the user has indicated that she wants to remove the specified
+ // autofill suggestion from the database.
+ virtual void RemoveAutofillEntry(const std::wstring& field_name,
+ const std::wstring& value) { }
+
// Notification that the page has an OpenSearch description document.
virtual void PageHasOSDD(RenderViewHost* render_view_host,
int32 page_id, const GURL& doc_url,
diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc
index d0edfa9..09c58f4 100644
--- a/chrome/browser/tab_contents/web_contents.cc
+++ b/chrome/browser/tab_contents/web_contents.cc
@@ -1213,6 +1213,11 @@ void WebContents::GetAutofillSuggestions(const std::wstring& field_name,
kMaxAutofillMenuItems, node_id, request_id);
}
+void WebContents::RemoveAutofillEntry(const std::wstring& field_name,
+ const std::wstring& value) {
+ GetAutofillManager()->RemoveValueForName(field_name, value);
+}
+
// Checks to see if we should generate a keyword based on the OSDD, and if
// necessary uses TemplateURLFetcher to download the OSDD and create a keyword.
void WebContents::PageHasOSDD(RenderViewHost* render_view_host,
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index 6e86268..8f46524 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -380,6 +380,8 @@ class WebContents : public TabContents,
virtual void AutofillFormSubmitted(const AutofillForm& form);
virtual void GetAutofillSuggestions(const std::wstring& field_name,
const std::wstring& user_text, int64 node_id, int request_id);
+ virtual void RemoveAutofillEntry(const std::wstring& field_name,
+ const std::wstring& value);
virtual void PageHasOSDD(RenderViewHost* render_view_host,
int32 page_id, const GURL& url, bool autodetected);
virtual void InspectElementReply(int num_resources);
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index 1687159..4f0dece 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -139,6 +139,20 @@ WebDataService::Handle WebDataService::GetFormValuesForElementName(
return request->GetHandle();
}
+void WebDataService::RemoveFormValueForElementName(
+ const std::wstring& name, const std::wstring& value) {
+ GenericRequest2<std::wstring, std::wstring>* request =
+ new GenericRequest2<std::wstring, std::wstring>(this,
+ GetNextRequestHandle(),
+ NULL,
+ name, value);
+ RegisterRequest(request);
+ ScheduleTask(
+ NewRunnableMethod(this,
+ &WebDataService::RemoveFormValueForElementNameImpl,
+ request));
+}
+
void WebDataService::RequestCompleted(Handle h) {
pending_lock_.Acquire();
RequestMap::iterator i = pending_requests_.find(h);
@@ -577,6 +591,16 @@ void WebDataService::RemoveFormElementsAddedBetweenImpl(
request->RequestComplete();
}
+void WebDataService::RemoveFormValueForElementNameImpl(
+ GenericRequest2<std::wstring, std::wstring>* request) {
+ if (db_ && !request->IsCancelled()) {
+ if (db_->RemoveFormElement(request->GetArgument1(),
+ request->GetArgument2()))
+ ScheduleCommit();
+ }
+ request->RequestComplete();
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// Web Apps implementation.
diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h
index e6fc18d..efeaf05 100644
--- a/chrome/browser/webdata/web_data_service.h
+++ b/chrome/browser/webdata/web_data_service.h
@@ -382,6 +382,8 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
// Removes form elements recorded for autofill from the database.
void RemoveFormElementsAddedBetween(const base::Time& delete_begin,
const base::Time& delete_end);
+ void RemoveFormValueForElementName(const std::wstring& name,
+ const std::wstring& value);
protected:
friend class TemplateURLModelTest;
@@ -460,6 +462,8 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
const std::wstring& name, const std::wstring& prefix, int limit);
void RemoveFormElementsAddedBetweenImpl(
GenericRequest2<base::Time, base::Time>* request);
+ void RemoveFormValueForElementNameImpl(
+ GenericRequest2<std::wstring, std::wstring>* request);
//////////////////////////////////////////////////////////////////////////////
//
diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc
index f98c4013..b9b64f3 100644
--- a/chrome/browser/webdata/web_database.cc
+++ b/chrome/browser/webdata/web_database.cc
@@ -868,7 +868,7 @@ bool WebDatabase::ClearAutofillEmptyValueElements() {
bool success = true;
for (std::set<int64>::const_iterator iter = ids.begin(); iter != ids.end();
++iter) {
- if (!RemoveFormElement(*iter))
+ if (!RemoveFormElementForID(*iter))
success = false;
}
@@ -1117,6 +1117,26 @@ bool WebDatabase::RemoveFormElementForTimeRange(int64 pair_id,
return result;
}
+bool WebDatabase::RemoveFormElement(const std::wstring& name,
+ const std::wstring& value) {
+ // Find the id for that pair.
+ SQLStatement s;
+ if (s.prepare(db_,
+ "SELECT pair_id FROM autofill WHERE name = ? AND value= ?") !=
+ SQLITE_OK) {
+ NOTREACHED() << "Statement 1 prepare failed";
+ return false;
+ }
+ s.bind_wstring(0, name);
+ s.bind_wstring(1, value);
+
+ int result = s.step();
+ if (result != SQLITE_ROW)
+ return false;
+
+ return RemoveFormElementForID(s.column_int64(0));
+}
+
bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) {
int count = 0;
@@ -1124,7 +1144,7 @@ bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) {
return false;
if (count + delta == 0) {
- if (!RemoveFormElement(pair_id))
+ if (!RemoveFormElementForID(pair_id))
return false;
} else {
if (!SetCountOfFormElement(pair_id, count + delta))
@@ -1133,7 +1153,7 @@ bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) {
return true;
}
-bool WebDatabase::RemoveFormElement(int64 pair_id) {
+bool WebDatabase::RemoveFormElementForID(int64 pair_id) {
SQLStatement s;
if (s.prepare(db_,
"DELETE FROM autofill WHERE pair_id = ?") != SQLITE_OK) {
diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h
index 95d4906..3584701 100644
--- a/chrome/browser/webdata/web_database.h
+++ b/chrome/browser/webdata/web_database.h
@@ -178,7 +178,10 @@ class WebDatabase {
bool InsertPairIDAndDate(int64 pair_id, const base::Time date_created);
// Removes row from the autofill tables given |pair_id|.
- bool RemoveFormElement(int64 pair_id);
+ bool RemoveFormElementForID(int64 pair_id);
+
+ // Removes row from the autofill tables for the given |name| |value| pair.
+ bool RemoveFormElement(const std::wstring& name, const std::wstring& value);
//////////////////////////////////////////////////////////////////////////////
//
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 2dbb924..bd13315 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1157,6 +1157,12 @@ IPC_BEGIN_MESSAGES(ViewHost)
int64 /* id of the text input field */,
int /* id of this message */)
+ // Instructs the browser to remove the specified autofill-entry from the
+ // database.
+ IPC_MESSAGE_ROUTED2(ViewHostMsg_RemoveAutofillEntry,
+ std::wstring /* field name */,
+ std::wstring /* value */)
+
// Get the list of proxies to use for |url|, as a semicolon delimited list
// of "<TYPE> <HOST>:<PORT>" | "DIRECT". See also
// PluginProcessHostMsg_ResolveProxy which does the same thing.
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 97c7c37..961c665 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1694,6 +1694,11 @@ void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
form_field_autofill_request_id_));
}
+void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
+ const std::wstring& value) {
+ Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
+}
+
void RenderView::OnReceivedAutofillSuggestions(
int64 node_id,
int request_id,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index ac898bf..b6d48a0 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -155,6 +155,8 @@ class RenderView : public RenderWidget,
virtual void QueryFormFieldAutofill(const std::wstring& field_name,
const std::wstring& text,
int64 node_id);
+ virtual void RemoveStoredAutofillEntry(const std::wstring& field_name,
+ const std::wstring& text);
virtual void UpdateTargetURL(WebView* webview,
const GURL& url);
virtual void RunFileChooser(bool multi_select,
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index b7e9d0d..a99e102 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -488,6 +488,11 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
int64 node_id) {
}
+ // Instructs the browser to remove the autofill entry specified from it DB.
+ virtual void RemoveStoredAutofillEntry(const std::wstring& name,
+ const std::wstring& value) {
+ }
+
// 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 8c86ff8..00bc668 100644
--- a/webkit/glue/webview_impl.cc
+++ b/webkit/glue/webview_impl.cc
@@ -268,6 +268,11 @@ class AutocompletePopupMenuClient : public WebCore::PopupMenuClient {
selected_index_ = -1;
}
+ void RemoveItemAtIndex(int index) {
+ DCHECK(index >= 0 && index < static_cast<int>(suggestions_.size()));
+ suggestions_.erase(suggestions_.begin() + index);
+ }
+
WebCore::HTMLInputElement* text_field() const {
return text_field_.get();
}
@@ -541,6 +546,35 @@ bool WebViewImpl::AutocompleteHandleKeyEvent(const WebKeyboardEvent& event) {
return false;
}
+ // Pressing delete triggers the removal of the selected suggestion from the
+ // DB.
+ if (event.windows_key_code == base::VKEY_DELETE &&
+ autocomplete_popup_->selectedIndex() != -1) {
+ Node* node = GetFocusedNode();
+ if (!node || (node->nodeType() != WebCore::Node::ELEMENT_NODE)) {
+ NOTREACHED();
+ return false;
+ }
+ WebCore::Element* element = static_cast<WebCore::Element*>(node);
+ if (!element->hasLocalName(WebCore::HTMLNames::inputTag)) {
+ NOTREACHED();
+ return false;
+ }
+
+ int selected_index = autocomplete_popup_->selectedIndex();
+ WebCore::HTMLInputElement* input_element =
+ static_cast<WebCore::HTMLInputElement*>(element);
+ std::wstring name = webkit_glue::StringToStdWString(input_element->name());
+ std::wstring value = webkit_glue::StringToStdWString(
+ autocomplete_popup_client_->itemText(selected_index ));
+ delegate()->RemoveStoredAutofillEntry(name, value);
+ // Update the entries in the currently showing popup to reflect the
+ // deletion.
+ autocomplete_popup_client_->RemoveItemAtIndex(selected_index);
+ RefreshAutofillPopup();
+ return false;
+ }
+
if (!autocomplete_popup_->isInterestedInEventForKey(event.windows_key_code))
return false;
@@ -1573,16 +1607,7 @@ void WebViewImpl::AutofillSuggestionsForNode(
if (autocomplete_popup_showing_) {
autocomplete_popup_client_->SetSuggestions(suggestions);
- IntRect old_bounds = autocomplete_popup_->boundsRect();
- autocomplete_popup_->refresh();
- IntRect new_bounds = autocomplete_popup_->boundsRect();
- // Let's resize the backing window if necessary.
- if (old_bounds != new_bounds) {
- WebWidgetImpl* web_widget =
- static_cast<WebWidgetImpl*>(autocomplete_popup_->client());
- web_widget->delegate()->SetWindowRect(
- web_widget, webkit_glue::FromIntRect(new_bounds));
- }
+ RefreshAutofillPopup();
} else {
autocomplete_popup_->show(focused_node->getRect(),
focused_node->ownerDocument()->view(), 0);
@@ -1690,6 +1715,20 @@ void WebViewImpl::HideAutofillPopup() {
HideAutoCompletePopup();
}
+void WebViewImpl::RefreshAutofillPopup() {
+ DCHECK(autocomplete_popup_showing_);
+ IntRect old_bounds = autocomplete_popup_->boundsRect();
+ autocomplete_popup_->refresh();
+ IntRect new_bounds = autocomplete_popup_->boundsRect();
+ // Let's resize the backing window if necessary.
+ if (old_bounds != new_bounds) {
+ WebWidgetImpl* web_widget =
+ static_cast<WebWidgetImpl*>(autocomplete_popup_->client());
+ web_widget->delegate()->SetWindowRect(
+ web_widget, webkit_glue::FromIntRect(new_bounds));
+ }
+}
+
Node* WebViewImpl::GetFocusedNode() {
Frame* frame = page_->focusController()->focusedFrame();
if (!frame)
diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h
index 4c6572d..debc82b 100644
--- a/webkit/glue/webview_impl.h
+++ b/webkit/glue/webview_impl.h
@@ -257,6 +257,11 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> {
// Returns true if the autocomple has consumed the event.
bool AutocompleteHandleKeyEvent(const WebKeyboardEvent& event);
+ // Repaints the autofill popup. Should be called when the suggestions have
+ // changed. Note that this should only be called when the autofill popup is
+ // showing.
+ void RefreshAutofillPopup();
+
// Returns true if the view was scrolled.
bool ScrollViewWithKeyboard(int key_code);