Skip to content

Commit

Permalink
Adding Mouse Support for new GTK Autofill
Browse files Browse the repository at this point in the history
Adds the ability use the mouse to select an Autofill option and see the preview of an option.

BUG=51644
TEST=


Review URL: http://codereview.chromium.org/9235072

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121234 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
csharp@chromium.org committed Feb 9, 2012
1 parent 6f7f89a commit 6f001a6
Show file tree
Hide file tree
Showing 20 changed files with 583 additions and 157 deletions.
33 changes: 9 additions & 24 deletions chrome/browser/autocomplete_history_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete_history_manager.h"
#include "chrome/browser/autofill/autofill_external_delegate.h"
#include "chrome/browser/autofill/test_autofill_external_delegate.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
Expand Down Expand Up @@ -139,17 +139,18 @@ TEST_F(AutocompleteHistoryManagerTest, SearchField) {

namespace {

class MockAutofillExternalDelegate : public AutofillExternalDelegate {
class MockAutofillExternalDelegate : public TestAutofillExternalDelegate {
public:
explicit MockAutofillExternalDelegate(TabContentsWrapper* wrapper)
: AutofillExternalDelegate(wrapper, NULL) {}
: TestAutofillExternalDelegate(wrapper, NULL) {}
virtual ~MockAutofillExternalDelegate() {}

virtual void OnQuery(int query_id,
const webkit::forms::FormData& form,
const webkit::forms::FormField& field,
const gfx::Rect& bounds,
bool display_warning) OVERRIDE {}
virtual void ApplyAutofillSuggestions(
const std::vector<string16>& autofill_values,
const std::vector<string16>& autofill_labels,
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids,
int separator_index) OVERRIDE {};

MOCK_METHOD5(OnSuggestionsReturned,
void(int query_id,
Expand All @@ -158,22 +159,6 @@ class MockAutofillExternalDelegate : public AutofillExternalDelegate {
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids));

virtual void HideAutofillPopup() OVERRIDE {}


virtual void ApplyAutofillSuggestions(
const std::vector<string16>& autofill_values,
const std::vector<string16>& autofill_labels,
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids,
int separator_index) OVERRIDE {}

virtual void OnQueryPlatformSpecific(
int query_id,
const webkit::forms::FormData& form,
const webkit::forms::FormField& field,
const gfx::Rect& bounds) OVERRIDE {}

private:
DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate);
};
Expand Down
96 changes: 85 additions & 11 deletions chrome/browser/autofill/autofill_external_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,34 @@ AutofillExternalDelegate::AutofillExternalDelegate(
autofill_manager_(autofill_manager),
autofill_query_id_(0),
display_warning_if_disabled_(false),
has_shown_autofill_popup_for_current_edit_(false) {
has_shown_autofill_popup_for_current_edit_(false),
suggestions_clear_index_(-1),
suggestions_options_index_(-1) {
}

void AutofillExternalDelegate::SelectAutofillSuggestionAtIndex(int listIndex) {
RenderViewHost* host =
tab_contents_wrapper_->web_contents()->GetRenderViewHost();
host->Send(new AutofillMsg_SelectAutofillSuggestionAtIndex(
host->routing_id(),
listIndex));
void AutofillExternalDelegate::SelectAutofillSuggestionAtIndex(int unique_id,
int list_index) {
if (list_index == suggestions_options_index_ ||
list_index == suggestions_clear_index_ ||
unique_id == -1)
return;

FillAutofillFormData(unique_id, true);
}

void AutofillExternalDelegate::OnQuery(int query_id,
const webkit::forms::FormData& form,
const webkit::forms::FormField& field,
const gfx::Rect& bounds,
bool display_warning_if_disabled) {
autofill_query_form_ = form;
autofill_query_field_ = field;
display_warning_if_disabled_ = display_warning_if_disabled;
autofill_query_id_ = query_id;

OnQueryPlatformSpecific(query_id, form, field, bounds);
}

void AutofillExternalDelegate::DidEndTextFieldEditing() {
has_shown_autofill_popup_for_current_edit_ = false;
}

void AutofillExternalDelegate::OnSuggestionsReturned(
int query_id,
const std::vector<string16>& values,
Expand Down Expand Up @@ -110,6 +111,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
l.push_back(string16());
i.push_back(string16());
ids.push_back(0);
suggestions_clear_index_ = v.size() - 1;
separator_index = v.size() - 1;
}

Expand All @@ -119,6 +121,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
l.push_back(string16());
i.push_back(string16());
ids.push_back(0);
suggestions_options_index_ = v.size() - 1;
separator_index = values.size();
}

Expand All @@ -131,6 +134,77 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
has_shown_autofill_popup_for_current_edit_ |= has_autofill_item;
}

void AutofillExternalDelegate::DidEndTextFieldEditing() {
has_shown_autofill_popup_for_current_edit_ = false;
}

void AutofillExternalDelegate::DidAcceptAutofillSuggestions(string16 value,
int unique_id,
unsigned index) {
// If the selected element is a warning we don't want to do anything.
if (unique_id < 0)
return;

// TODO(csharp): Add the password autofill manager.
// if (password_autofill_manager_->DidAcceptAutofillSuggestion(node, value))
// return;

if (suggestions_options_index_ != -1 &&
index == static_cast<unsigned>(suggestions_options_index_)) {
// User selected 'Autofill Options'.
autofill_manager_->OnShowAutofillDialog();
} else if (suggestions_clear_index_ != -1 &&
index == static_cast<unsigned>(suggestions_clear_index_)) {
// User selected 'Clear form'.
RenderViewHost* host =
tab_contents_wrapper_->web_contents()->GetRenderViewHost();
host->Send(new AutofillMsg_ClearForm(host->routing_id()));
} else if (!unique_id) {
// User selected an Autocomplete entry, so we fill directly.
RenderViewHost* host =
tab_contents_wrapper_->web_contents()->GetRenderViewHost();
host->Send(new AutofillMsg_SetNodeText(
host->routing_id(),
value));
} else {
FillAutofillFormData(unique_id, false);
}

HideAutofillPopup();
}

void AutofillExternalDelegate::ClearPreviewedForm() {
RenderViewHost* host =
tab_contents_wrapper_->web_contents()->GetRenderViewHost();
host->Send(new AutofillMsg_ClearPreviewedForm(host->routing_id()));
}

void AutofillExternalDelegate::HideAutofillPopup() {
suggestions_clear_index_ = -1;
suggestions_options_index_ = -1;

HideAutofillPopupInternal();
}

void AutofillExternalDelegate::FillAutofillFormData(int unique_id,
bool is_preview) {
RenderViewHost* host =
tab_contents_wrapper_->web_contents()->GetRenderViewHost();

if (is_preview) {
host->Send(new AutofillMsg_SetAutofillActionPreview(
host->routing_id()));
} else {
host->Send(new AutofillMsg_SetAutofillActionFill(
host->routing_id()));
}

// Fill the values for the whole form.
autofill_manager_->OnFillAutofillFormData(autofill_query_id_,
autofill_query_form_,
autofill_query_field_,
unique_id);
}

// Add a "!defined(OS_YOUROS) for each platform that implements this
// in an autofill_external_delegate_YOUROS.cc. Currently there are
Expand Down
47 changes: 33 additions & 14 deletions chrome/browser/autofill/autofill_external_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

#include <vector>

#include "base/compiler_specific.h"
#include "base/string16.h"
#include "webkit/forms/form_data.h"
#include "webkit/forms/form_field.h"

class AutofillManager;
Expand All @@ -18,12 +20,6 @@ namespace gfx {
class Rect;
}

namespace webkit {
namespace forms {
struct FormData;
}
}

// TODO(csharp): A lot of the logic in this class is copied from autofillagent.
// Once Autofill is moved out of WebKit this class should be the only home for
// this logic. See http://crbug.com/51644
Expand All @@ -37,7 +33,7 @@ class AutofillExternalDelegate {
// When using an external Autofill delegate. Allows Chrome to tell
// WebKit which Autofill selection has been chosen.
// TODO(jrg): add feedback mechanism for hover on relevant platforms.
void SelectAutofillSuggestionAtIndex(int listIndex);
virtual void SelectAutofillSuggestionAtIndex(int unique_id, int list_index);

// Records and associates a query_id with web form data. Called
// when the renderer posts an Autofill query to the browser. |bounds|
Expand All @@ -61,20 +57,27 @@ class AutofillExternalDelegate {
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids);

// Inform the delegate that the text field editing has ended, this is
// used to help record the metrics of when a new popup is shown.
void DidEndTextFieldEditing();

// Inform the delegate that an autofill suggestion have been chosen.
void DidAcceptAutofillSuggestions(string16 value,
int unique_id,
unsigned index);

// Informs the delegate that the Autofill previewed form should be cleared.
virtual void ClearPreviewedForm();

// Hide the Autofill poup.
virtual void HideAutofillPopup() = 0;
virtual void HideAutofillPopup();

// Platforms that wish to implement an external Autofill delegate
// MUST implement this. The 1st arg is the tab contents that owns
// this delegate; the second is the Autofill manager owned by the
// tab contents.
static AutofillExternalDelegate* Create(TabContentsWrapper*,
AutofillManager*);

// Inform the delegate that the text field editing has ended, this is
// used to help record the metrics of when a new popup is shown.
void DidEndTextFieldEditing();

protected:
explicit AutofillExternalDelegate(TabContentsWrapper* tab_contents_wrapper,
AutofillManager* autofill_manager);
Expand All @@ -95,15 +98,25 @@ class AutofillExternalDelegate {
const webkit::forms::FormField& field,
const gfx::Rect& bounds) = 0;

// Handle platform-dependent hiding.
virtual void HideAutofillPopupInternal() = 0;

private:
// Fills the form with the Autofill data corresponding to |unique_id|.
// If |is_preview| is true then this is just a preview to show the user what
// would be selected and if |is_preview| is false then the user has selected
// this data.
void FillAutofillFormData(int unique_id, bool is_preview);

TabContentsWrapper* tab_contents_wrapper_; // weak; owns me.
AutofillManager* autofill_manager_; // weak.

// The ID of the last request sent for form field Autofill. Used to ignore
// out of date responses.
int autofill_query_id_;

// The current field selected by Autofill.
// The current form and field selected by Autofill.
webkit::forms::FormData autofill_query_form_;
webkit::forms::FormField autofill_query_field_;

// Should we display a warning if Autofill is disabled?
Expand All @@ -113,6 +126,12 @@ class AutofillExternalDelegate {
// currently editing? Used to keep track of state for metrics logging.
bool has_shown_autofill_popup_for_current_edit_;

// The menu index of the "Clear" menu item.
int suggestions_clear_index_;

// The menu index of the "Autofill options..." menu item.
int suggestions_options_index_;

DISALLOW_COPY_AND_ASSIGN(AutofillExternalDelegate);
};

Expand Down
23 changes: 12 additions & 11 deletions chrome/browser/autofill/autofill_external_delegate_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ AutofillExternalDelegateGtk::AutofillExternalDelegateGtk(
AutofillExternalDelegateGtk::~AutofillExternalDelegateGtk() {
}

void AutofillExternalDelegateGtk::HideAutofillPopupInternal() {
if (!view_.get())
return;

view_->Hide();
view_.reset();

GtkWidget* toplevel = gtk_widget_get_toplevel(tab_native_view_);
g_signal_handler_disconnect(toplevel, event_handler_id_);
}

void AutofillExternalDelegateGtk::OnQueryPlatformSpecific(
int query_id,
const webkit::forms::FormData& form,
Expand All @@ -50,22 +61,12 @@ void AutofillExternalDelegateGtk::ApplyAutofillSuggestions(
separator_index);
}

void AutofillExternalDelegateGtk::HideAutofillPopup() {
if (!view_.get())
return;

view_->Hide();
view_.reset();

GtkWidget* toplevel = gtk_widget_get_toplevel(tab_native_view_);
g_signal_handler_disconnect(toplevel, event_handler_id_);
}

void AutofillExternalDelegateGtk::CreateViewIfNeeded() {
if (view_.get())
return;

view_.reset(new AutofillPopupViewGtk(web_contents_,
this,
tab_native_view_));

GtkWidget* toplevel = gtk_widget_get_toplevel(tab_native_view_);
Expand Down
4 changes: 1 addition & 3 deletions chrome/browser/autofill/autofill_external_delegate_gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ class AutofillExternalDelegateGtk : public AutofillExternalDelegate {

virtual ~AutofillExternalDelegateGtk();

// AutofillExternalDelegate implementation.
virtual void HideAutofillPopup() OVERRIDE;

protected:
// AutofillExternalDelegate implementations.
virtual void HideAutofillPopupInternal() OVERRIDE;
virtual void OnQueryPlatformSpecific(
int query_id,
const webkit::forms::FormData& form,
Expand Down
Loading

0 comments on commit 6f001a6

Please sign in to comment.