| 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 979976f72c14ee71c8dfd95e7bf5c195d680aedb..88ca506373d7d9924d0d6d52f63104115ddceb74 100644
|
| --- a/components/autofill/content/renderer/autofill_agent.cc
|
| +++ b/components/autofill/content/renderer/autofill_agent.cc
|
| @@ -55,6 +55,7 @@ using blink::WebNode;
|
| using blink::WebNodeCollection;
|
| using blink::WebOptionElement;
|
| using blink::WebString;
|
| +using blink::WebTextAreaElement;
|
|
|
| namespace autofill {
|
|
|
| @@ -293,7 +294,15 @@ void AutofillAgent::InputElementClicked(const WebInputElement& element,
|
| ShowSuggestions(element, true, false, true, false);
|
| }
|
|
|
| -void AutofillAgent::InputElementLostFocus() {
|
| +void AutofillAgent::TextAreaElementClicked(const WebTextAreaElement& element,
|
| + bool was_focused,
|
| + bool is_focused) {
|
| + if (was_focused)
|
| + ShowSuggestions(element, true, false, true, false);
|
| +}
|
| +
|
| +// This applies to both input and textarea elements
|
| +void AutofillAgent::FormControlElementLostFocus() {
|
| HideAutofillUI();
|
| }
|
|
|
| @@ -303,7 +312,8 @@ void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) {
|
| Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id()));
|
| }
|
|
|
| -void AutofillAgent::textFieldDidChange(const WebInputElement& element) {
|
| +// Text changes in input text field or textarea field
|
| +void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) {
|
| if (ignore_text_changes_)
|
| return;
|
|
|
| @@ -323,27 +333,36 @@ 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 (IsAutofillableInputElement(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 ((IsAutofillableInputElement(input_element) ||
|
| + IsTextAreaElement(element)) &&
|
| + FindFormAndFieldForFormControlElement(element,
|
| + &form,
|
| + &field,
|
| + REQUIRE_NONE)) {
|
| Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field,
|
| base::TimeTicks::Now()));
|
| }
|
| @@ -367,14 +386,15 @@ void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
|
|
|
| void AutofillAgent::AcceptDataListSuggestion(
|
| const base::string16& suggested_value) {
|
| + WebInputElement* input_element = toWebInputElement(&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());
|
|
|
| @@ -391,7 +411,7 @@ void AutofillAgent::AcceptDataListSuggestion(
|
|
|
| new_value = JoinString(parts, ',');
|
| }
|
| - SetNodeText(new_value, &element_);
|
| + SetNodeText(new_value, input_element);
|
| }
|
|
|
| void AutofillAgent::OnFormDataFilled(int query_id,
|
| @@ -453,7 +473,8 @@ void AutofillAgent::OnClearPreviewedForm() {
|
| }
|
|
|
| void AutofillAgent::OnSetNodeText(const base::string16& value) {
|
| - SetNodeText(value, &element_);
|
| + WebInputElement* input_element = toWebInputElement(&element_);
|
| + SetNodeText(value, input_element);
|
| }
|
|
|
| void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) {
|
| @@ -489,34 +510,42 @@ void AutofillAgent::OnRequestAutocompleteResult(
|
| void AutofillAgent::OnPageShown() {
|
| }
|
|
|
| -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())
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
| + if (!element.isEnabled() || element.isReadOnly())
|
| return;
|
|
|
| - // Don't attempt to autofill with values that are too large or if filling
|
| - // criteria are not met.
|
| - WebString value = element.editingValue();
|
| - if (!datalist_only &&
|
| - (value.length() > kMaxDataLength ||
|
| - (!autofill_on_empty_values && value.isEmpty()) ||
|
| - (requires_caret_at_end &&
|
| - (element.selectionStart() != element.selectionEnd() ||
|
| - element.selectionEnd() != static_cast<int>(value.length()))))) {
|
| - // Any popup currently showing is obsolete.
|
| - HideAutofillUI();
|
| + if (IsAutofillableInputElement(input_element)) {
|
| + if (!input_element->isTextField() || input_element->isPasswordField())
|
| + return;
|
| + if (!datalist_only && !input_element->suggestedValue().isEmpty())
|
| + return;
|
| + // Don't attempt to autofill with values that are too large or if filling
|
| + // criteria are not met.
|
| + WebString value = input_element->editingValue();
|
| + if (!datalist_only &&
|
| + (value.length() > kMaxDataLength ||
|
| + (!autofill_on_empty_values && value.isEmpty()) ||
|
| + (requires_caret_at_end &&
|
| + (input_element->selectionStart() != input_element->selectionEnd() ||
|
| + input_element->selectionEnd() !=
|
| + static_cast<int>(value.length()))))) {
|
| + // Any popup currently showing is obsolete.
|
| + HideAutofillUI();
|
| + return;
|
| + }
|
| +
|
| + if (password_autofill_agent_->ShowSuggestions(*input_element))
|
| + return;
|
| + } else if (IsTextAreaElement(element) &&
|
| + !element.toConst<WebTextAreaElement>().suggestedValue().isEmpty())
|
| return;
|
| - }
|
|
|
| element_ = element;
|
| - if (password_autofill_agent_->ShowSuggestions(element))
|
| - return;
|
|
|
| // If autocomplete is disabled at the field level, ensure that the native
|
| // UI won't try to show a warning, since that may conflict with a custom
|
| @@ -533,27 +562,32 @@ 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;
|
|
|
| static int query_counter = 0;
|
| autofill_query_id_ = query_counter++;
|
| display_warning_if_disabled_ = display_warning_if_disabled;
|
| + const WebInputElement* input_element = toWebInputElement(&element);
|
|
|
| // If autocomplete is disabled at the form level, we want to see if there
|
| // would have been any suggestions were it enabled, so that we can show a
|
| // warning. Otherwise, we want to ignore fields that disable autocomplete, so
|
| // that the suggestions list does not include suggestions for these form
|
| // fields -- see comment 1 on http://crbug.com/69914
|
| - const RequirementsMask requirements =
|
| - element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE;
|
| + RequirementsMask requirements = REQUIRE_NONE;
|
| + if (IsAutofillableInputElement(input_element))
|
| + requirements =
|
| + input_element->autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE;
|
|
|
| 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);
|
| @@ -564,20 +598,21 @@ 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_,
|
| + if (IsAutofillableInputElement(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);
|
| + TrimStringVectorForIPC(&data_list_values);
|
| + TrimStringVectorForIPC(&data_list_labels);
|
|
|
| - Send(new AutofillHostMsg_SetDataList(routing_id(),
|
| + Send(new AutofillHostMsg_SetDataList(routing_id(),
|
| data_list_values,
|
| data_list_labels));
|
| -
|
| + }
|
| Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
|
| autofill_query_id_,
|
| form,
|
| @@ -596,8 +631,11 @@ void AutofillAgent::FillAutofillFormData(const WebNode& node,
|
|
|
| FormData form;
|
| FormFieldData field;
|
| - if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form,
|
| - &field, REQUIRE_AUTOCOMPLETE)) {
|
| + if (!FindFormAndFieldForFormControlElement(
|
| + node.toConst<WebFormControlElement>(),
|
| + &form,
|
| + &field,
|
| + REQUIRE_AUTOCOMPLETE)) {
|
| return;
|
| }
|
|
|
|
|