| Index: components/autofill/content/renderer/autofill_agent.cc
|
| diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
|
| index 5f3b03043eb0d6793db7fb47026ea428a26ab0ec..044aa12a6d82ba7ca7e08dc6be347a23fa8cece9 100644
|
| --- a/components/autofill/content/renderer/autofill_agent.cc
|
| +++ b/components/autofill/content/renderer/autofill_agent.cc
|
| @@ -41,6 +41,7 @@
|
| #include "third_party/WebKit/public/web/WebInputEvent.h"
|
| #include "third_party/WebKit/public/web/WebNode.h"
|
| #include "third_party/WebKit/public/web/WebOptionElement.h"
|
| +#include "third_party/WebKit/public/web/WebTextAreaElement.h"
|
| #include "third_party/WebKit/public/web/WebView.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "ui/events/keycodes/keyboard_codes.h"
|
| @@ -56,6 +57,7 @@ using blink::WebKeyboardEvent;
|
| using blink::WebNode;
|
| using blink::WebOptionElement;
|
| using blink::WebString;
|
| +using blink::WebTextAreaElement;
|
| using blink::WebVector;
|
|
|
| namespace autofill {
|
| @@ -296,14 +298,18 @@ void AutofillAgent::setIgnoreTextChanges(bool ignore) {
|
| ignore_text_changes_ = ignore;
|
| }
|
|
|
| -void AutofillAgent::InputElementClicked(const WebInputElement& element,
|
| - bool was_focused,
|
| - bool is_focused) {
|
| +void AutofillAgent::FormControlElementClicked(
|
| + const WebFormControlElement& element,
|
| + bool was_focused) {
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
| + if (!input_element && !IsTextAreaElement(element))
|
| + return;
|
| +
|
| if (was_focused)
|
| ShowSuggestions(element, true, false, true, false);
|
| }
|
|
|
| -void AutofillAgent::InputElementLostFocus() {
|
| +void AutofillAgent::FormControlElementLostFocus() {
|
| HidePopup();
|
| }
|
|
|
| @@ -313,10 +319,19 @@ void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) {
|
| Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id()));
|
| }
|
|
|
| +// TODO(ziran.sun): This function is to be removed once next Blink roll is done
|
| void AutofillAgent::textFieldDidChange(const WebInputElement& element) {
|
| + const WebFormControlElement control_element =
|
| + element.toConst<WebFormControlElement>();
|
| + textFieldDidChange(control_element);
|
| +}
|
| +
|
| +void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) {
|
| if (ignore_text_changes_)
|
| return;
|
|
|
| + DCHECK(toWebInputElement(&element) || IsTextAreaElement(element));
|
| +
|
| if (did_set_node_text_) {
|
| did_set_node_text_ = false;
|
| return;
|
| @@ -333,27 +348,34 @@ void AutofillAgent::textFieldDidChange(const WebInputElement& element) {
|
| element));
|
| }
|
|
|
| -void AutofillAgent::TextFieldDidChangeImpl(const WebInputElement& element) {
|
| +void AutofillAgent::TextFieldDidChangeImpl(
|
| + const WebFormControlElement& element) {
|
| // If the element isn't focused then the changes don't matter. This check is
|
| // required to properly handle IME interactions.
|
| if (!element.focused())
|
| return;
|
|
|
| - if (password_generation_agent_ &&
|
| - password_generation_agent_->TextDidChangeInTextField(element)) {
|
| - return;
|
| - }
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
| + if (input_element) {
|
| + if (password_generation_agent_ &&
|
| + password_generation_agent_->TextDidChangeInTextField(*input_element)) {
|
| + return;
|
| + }
|
|
|
| - if (password_autofill_agent_->TextDidChangeInTextField(element)) {
|
| - element_ = element;
|
| - return;
|
| + if (password_autofill_agent_->TextDidChangeInTextField(*input_element)) {
|
| + element_ = element;
|
| + return;
|
| + }
|
| }
|
|
|
| ShowSuggestions(element, false, true, false, false);
|
|
|
| FormData form;
|
| FormFieldData field;
|
| - if (FindFormAndFieldForInputElement(element, &form, &field, REQUIRE_NONE)) {
|
| + if (FindFormAndFieldForFormControlElement(element,
|
| + &form,
|
| + &field,
|
| + REQUIRE_NONE)) {
|
| Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field,
|
| base::TimeTicks::Now()));
|
| }
|
| @@ -377,14 +399,16 @@ void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
|
|
|
| void AutofillAgent::AcceptDataListSuggestion(
|
| const base::string16& suggested_value) {
|
| + WebInputElement* input_element = toWebInputElement(&element_);
|
| + DCHECK(input_element);
|
| base::string16 new_value = suggested_value;
|
| // If this element takes multiple values then replace the last part with
|
| // the suggestion.
|
| - if (element_.isMultiple() &&
|
| - element_.formControlType() == WebString::fromUTF8("email")) {
|
| + if (input_element->isMultiple() &&
|
| + input_element->formControlType() == WebString::fromUTF8("email")) {
|
| std::vector<base::string16> parts;
|
|
|
| - base::SplitStringDontTrim(element_.editingValue(), ',', &parts);
|
| + base::SplitStringDontTrim(input_element->editingValue(), ',', &parts);
|
| if (parts.size() == 0)
|
| parts.push_back(base::string16());
|
|
|
| @@ -401,7 +425,7 @@ void AutofillAgent::AcceptDataListSuggestion(
|
|
|
| new_value = JoinString(parts, ',');
|
| }
|
| - FillFieldWithValue(new_value, &element_);
|
| + FillFieldWithValue(new_value, input_element);
|
| }
|
|
|
| void AutofillAgent::OnFieldTypePredictionsAvailable(
|
| @@ -451,11 +475,15 @@ void AutofillAgent::OnClearPreviewedForm() {
|
| }
|
|
|
| void AutofillAgent::OnFillFieldWithValue(const base::string16& value) {
|
| - FillFieldWithValue(value, &element_);
|
| + WebInputElement* input_element = toWebInputElement(&element_);
|
| + if (input_element)
|
| + FillFieldWithValue(value, input_element);
|
| }
|
|
|
| void AutofillAgent::OnPreviewFieldWithValue(const base::string16& value) {
|
| - PreviewFieldWithValue(value, &element_);
|
| + WebInputElement* input_element = toWebInputElement(&element_);
|
| + if (input_element)
|
| + PreviewFieldWithValue(value, input_element);
|
| }
|
|
|
| void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) {
|
| @@ -489,17 +517,26 @@ void AutofillAgent::OnRequestAutocompleteResult(
|
| in_flight_request_form_.reset();
|
| }
|
|
|
| -void AutofillAgent::ShowSuggestions(const WebInputElement& element,
|
| +void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
|
| bool autofill_on_empty_values,
|
| bool requires_caret_at_end,
|
| bool display_warning_if_disabled,
|
| bool datalist_only) {
|
| - if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
|
| - element.isPasswordField())
|
| - return;
|
| - if (!datalist_only && !element.suggestedValue().isEmpty())
|
| + if (!element.isEnabled() || element.isReadOnly())
|
| return;
|
|
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
| + if (input_element) {
|
| + if (!input_element->isTextField() || input_element->isPasswordField())
|
| + return;
|
| + if (!datalist_only && !input_element->suggestedValue().isEmpty())
|
| + return;
|
| + } else {
|
| + DCHECK(IsTextAreaElement(element));
|
| + if (!element.toConst<WebTextAreaElement>().suggestedValue().isEmpty())
|
| + return;
|
| + }
|
| +
|
| // Don't attempt to autofill with values that are too large or if filling
|
| // criteria are not met.
|
| WebString value = element.editingValue();
|
| @@ -515,7 +552,8 @@ void AutofillAgent::ShowSuggestions(const WebInputElement& element,
|
| }
|
|
|
| element_ = element;
|
| - if (password_autofill_agent_->ShowSuggestions(element)) {
|
| + if (input_element &&
|
| + password_autofill_agent_->ShowSuggestions(*input_element)) {
|
| is_popup_possibly_visible_ = true;
|
| return;
|
| }
|
| @@ -535,12 +573,15 @@ void AutofillAgent::ShowSuggestions(const WebInputElement& element,
|
| datalist_only);
|
| }
|
|
|
| -void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element,
|
| - bool display_warning_if_disabled,
|
| - bool datalist_only) {
|
| +void AutofillAgent::QueryAutofillSuggestions(
|
| + const WebFormControlElement& element,
|
| + bool display_warning_if_disabled,
|
| + bool datalist_only) {
|
| if (!element.document().frame())
|
| return;
|
|
|
| + DCHECK(toWebInputElement(&element) || IsTextAreaElement(element));
|
| +
|
| static int query_counter = 0;
|
| autofill_query_id_ = query_counter++;
|
| display_warning_if_disabled_ = display_warning_if_disabled;
|
| @@ -555,7 +596,8 @@ void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element,
|
|
|
| FormData form;
|
| FormFieldData field;
|
| - if (!FindFormAndFieldForInputElement(element, &form, &field, requirements)) {
|
| + if (!FindFormAndFieldForFormControlElement(element, &form, &field,
|
| + requirements)) {
|
| // If we didn't find the cached form, at least let autocomplete have a shot
|
| // at providing suggestions.
|
| WebFormControlElementToFormField(element, EXTRACT_VALUE, &field);
|
| @@ -566,21 +608,24 @@ void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element,
|
| gfx::RectF bounding_box_scaled =
|
| GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_);
|
|
|
| - // Find the datalist values and send them to the browser process.
|
| - std::vector<base::string16> data_list_values;
|
| - std::vector<base::string16> data_list_labels;
|
| - GetDataListSuggestions(element_,
|
| - datalist_only,
|
| - &data_list_values,
|
| - &data_list_labels);
|
| - TrimStringVectorForIPC(&data_list_values);
|
| - TrimStringVectorForIPC(&data_list_labels);
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
| + if (input_element) {
|
| + // Find the datalist values and send them to the browser process.
|
| + std::vector<base::string16> data_list_values;
|
| + std::vector<base::string16> data_list_labels;
|
| + GetDataListSuggestions(*input_element,
|
| + datalist_only,
|
| + &data_list_values,
|
| + &data_list_labels);
|
| + TrimStringVectorForIPC(&data_list_values);
|
| + TrimStringVectorForIPC(&data_list_labels);
|
| +
|
| + Send(new AutofillHostMsg_SetDataList(routing_id(),
|
| + data_list_values,
|
| + data_list_labels));
|
| + }
|
|
|
| is_popup_possibly_visible_ = true;
|
| - Send(new AutofillHostMsg_SetDataList(routing_id(),
|
| - data_list_values,
|
| - data_list_labels));
|
| -
|
| Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
|
| autofill_query_id_,
|
| form,
|
|
|