diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 22:28:17 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 22:28:17 +0000 |
commit | 4d2b6fb574d019dab4080b3713d3d5e5aa0a91bd (patch) | |
tree | e384f04d2a7bc8403cf19929d84447782d6c7871 | |
parent | e08a579d8d6701fa48eac6945248855bbb5a70a6 (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | chrome/browser/autofill_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 7 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 2 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host_delegate.h | 5 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.cc | 5 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents.h | 2 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service.cc | 24 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service.h | 4 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database.cc | 26 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database.h | 5 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 6 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 5 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 2 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 5 | ||||
-rw-r--r-- | webkit/glue/webview_impl.cc | 59 | ||||
-rw-r--r-- | webkit/glue/webview_impl.h | 5 |
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); |