Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/content/renderer/form_autofill_util.h" | 5 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 NOTREACHED(); | 500 NOTREACHED(); |
| 501 continue; | 501 continue; |
| 502 } | 502 } |
| 503 | 503 |
| 504 bool is_initiating_element = (*element == initiating_element); | 504 bool is_initiating_element = (*element == initiating_element); |
| 505 | 505 |
| 506 // Only autofill empty fields and the field that initiated the filling, | 506 // Only autofill empty fields and the field that initiated the filling, |
| 507 // i.e. the field the user is currently editing and interacting with. | 507 // i.e. the field the user is currently editing and interacting with. |
| 508 const WebInputElement* input_element = toWebInputElement(element); | 508 const WebInputElement* input_element = toWebInputElement(element); |
| 509 if (!force_override && !is_initiating_element && | 509 if (!force_override && !is_initiating_element && |
| 510 ((IsAutofillableInputElement(input_element) && | 510 ((IsAutofillableInputElement(input_element) || |
|
Ilya Sherman
2014/03/14 07:24:46
nit: No need for the first parenthesis on this lin
ziran.sun
2014/03/14 17:01:42
I feel that it's still needed. The condition is -
Ilya Sherman
2014/03/14 21:42:55
Sorry, you're absolutely right. Thanks for correc
| |
| 511 !input_element->value().isEmpty()) || | 511 IsTextAreaElement(*element)) && |
| 512 (IsTextAreaElement(*element) && | 512 !element->value().isEmpty())) |
| 513 !element->toConst<WebTextAreaElement>().value().isEmpty()))) | |
| 514 continue; | 513 continue; |
| 515 | 514 |
| 516 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || | 515 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || |
| 517 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || | 516 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || |
| 518 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) | 517 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) |
| 519 continue; | 518 continue; |
| 520 | 519 |
| 521 callback(data.fields[i], is_initiating_element, element); | 520 callback(data.fields[i], is_initiating_element, element); |
| 522 } | 521 } |
| 523 } | 522 } |
| 524 | 523 |
| 525 // Sets the |field|'s value to the value in |data|. | 524 // Sets the |field|'s value to the value in |data|. |
| 526 // Also sets the "autofilled" attribute, causing the background to be yellow. | 525 // Also sets the "autofilled" attribute, causing the background to be yellow. |
| 527 void FillFormField(const FormFieldData& data, | 526 void FillFormField(const FormFieldData& data, |
| 528 bool is_initiating_node, | 527 bool is_initiating_node, |
| 529 blink::WebFormControlElement* field) { | 528 blink::WebFormControlElement* field) { |
| 530 // Nothing to fill. | 529 // Nothing to fill. |
| 531 if (data.value.empty()) | 530 if (data.value.empty()) |
| 532 return; | 531 return; |
| 533 | 532 |
| 534 field->setAutofilled(true); | 533 field->setAutofilled(true); |
| 535 | 534 |
| 536 WebInputElement* input_element = toWebInputElement(field); | 535 WebInputElement* input_element = toWebInputElement(field); |
| 537 if (IsTextInput(input_element) || IsMonthInput(input_element)) { | 536 if (IsTextInput(input_element) || IsMonthInput(input_element)) { |
| 538 // If the maxlength attribute contains a negative value, maxLength() | 537 // If the maxlength attribute contains a negative value, maxLength() |
| 539 // returns the default maxlength value. | 538 // returns the default maxlength value. |
| 540 input_element->setValue( | 539 input_element->setValue( |
| 541 data.value.substr(0, input_element->maxLength()), true); | 540 data.value.substr(0, input_element->maxLength()), true); |
| 542 if (is_initiating_node) { | 541 } else if ((IsTextAreaElement(*field) || IsSelectElement(*field)) && |
| 543 int length = input_element->value().length(); | 542 field->value() != data.value) { |
| 544 input_element->setSelectionRange(length, length); | 543 field->setValue(data.value); |
| 545 // Clear the current IME composition (the underline), if there is one. | 544 field->dispatchFormControlChangeEvent(); |
| 546 input_element->document().frame()->unmarkText(); | |
| 547 } | |
| 548 } else if (IsTextAreaElement(*field)) { | |
| 549 WebTextAreaElement text_area = field->to<WebTextAreaElement>(); | |
| 550 if (text_area.value() != data.value) { | |
| 551 text_area.setValue(data.value); | |
| 552 text_area.dispatchFormControlChangeEvent(); | |
| 553 } | |
| 554 } else if (IsSelectElement(*field)) { | |
| 555 WebSelectElement select_element = field->to<WebSelectElement>(); | |
| 556 if (select_element.value() != data.value) { | |
| 557 select_element.setValue(data.value); | |
| 558 select_element.dispatchFormControlChangeEvent(); | |
| 559 } | |
| 560 } else { | 545 } else { |
| 561 DCHECK(IsCheckableElement(input_element)); | 546 DCHECK(IsCheckableElement(input_element)); |
| 562 input_element->setChecked(data.is_checked, true); | 547 input_element->setChecked(data.is_checked, true); |
| 563 } | 548 } |
| 549 | |
| 550 if (is_initiating_node && | |
| 551 ((IsTextInput(input_element) || IsMonthInput(input_element)) || | |
| 552 IsTextAreaElement(*field))) { | |
| 553 int length = field->value().length(); | |
| 554 field->setSelectionRange(length, length); | |
| 555 // Clear the current IME composition (the underline), if there is one. | |
| 556 field->document().frame()->unmarkText(); | |
| 557 } | |
| 564 } | 558 } |
| 565 | 559 |
| 566 // Sets the |field|'s "suggested" (non JS visible) value to the value in |data|. | 560 // Sets the |field|'s "suggested" (non JS visible) value to the value in |data|. |
| 567 // Also sets the "autofilled" attribute, causing the background to be yellow. | 561 // Also sets the "autofilled" attribute, causing the background to be yellow. |
| 568 void PreviewFormField(const FormFieldData& data, | 562 void PreviewFormField(const FormFieldData& data, |
| 569 bool is_initiating_node, | 563 bool is_initiating_node, |
| 570 blink::WebFormControlElement* field) { | 564 blink::WebFormControlElement* field) { |
| 571 // Nothing to preview. | 565 // Nothing to preview. |
| 572 if (data.value.empty()) | 566 if (data.value.empty()) |
| 573 return; | 567 return; |
| 574 | 568 |
| 575 // Preview input and textarea fields. For input fields, excludes checkboxes | 569 // Preview input and textarea fields. For input fields, excludes checkboxes |
| 576 // and radio buttons, as there is no provision for setSuggestedCheckedValue | 570 // and radio buttons, as there is no provision for setSuggestedCheckedValue |
| 577 // in WebInputElement. | 571 // in WebInputElement. |
| 578 WebInputElement* input_element = toWebInputElement(field); | 572 WebInputElement* input_element = toWebInputElement(field); |
| 579 if (IsTextInput(input_element) || IsMonthInput(input_element)) { | 573 if (IsTextInput(input_element) || IsMonthInput(input_element)) { |
| 580 // If the maxlength attribute contains a negative value, maxLength() | 574 // If the maxlength attribute contains a negative value, maxLength() |
| 581 // returns the default maxlength value. | 575 // returns the default maxlength value. |
| 582 input_element->setSuggestedValue( | 576 input_element->setSuggestedValue( |
| 583 data.value.substr(0, input_element->maxLength())); | 577 data.value.substr(0, input_element->maxLength())); |
| 584 input_element->setAutofilled(true); | 578 input_element->setAutofilled(true); |
| 585 if (is_initiating_node) { | |
| 586 // Select the part of the text that the user didn't type. | |
| 587 input_element->setSelectionRange( | |
| 588 input_element->value().length(), | |
| 589 input_element->suggestedValue().length()); | |
| 590 } | |
| 591 } else if (IsTextAreaElement(*field)) { | 579 } else if (IsTextAreaElement(*field)) { |
| 592 WebTextAreaElement textarea = field->to<WebTextAreaElement>(); | 580 field->setSuggestedValue(data.value); |
| 593 textarea.setSuggestedValue(data.value); | |
| 594 field->setAutofilled(true); | 581 field->setAutofilled(true); |
| 595 } | 582 } |
| 583 | |
| 584 if (is_initiating_node && | |
| 585 (IsTextInput(input_element) || IsTextAreaElement(*field))) { | |
| 586 // Select the part of the text that the user didn't type. | |
| 587 int start = field->value().length(); | |
| 588 int end = field->suggestedValue().length(); | |
| 589 field->setSelectionRange(start, end); | |
| 590 } | |
| 596 } | 591 } |
| 597 | 592 |
| 598 std::string RetrievalMethodToString( | 593 std::string RetrievalMethodToString( |
| 599 const WebElementDescriptor::RetrievalMethod& method) { | 594 const WebElementDescriptor::RetrievalMethod& method) { |
| 600 switch (method) { | 595 switch (method) { |
| 601 case WebElementDescriptor::CSS_SELECTOR: | 596 case WebElementDescriptor::CSS_SELECTOR: |
| 602 return "CSS_SELECTOR"; | 597 return "CSS_SELECTOR"; |
| 603 case WebElementDescriptor::ID: | 598 case WebElementDescriptor::ID: |
| 604 return "ID"; | 599 return "ID"; |
| 605 case WebElementDescriptor::NONE: | 600 case WebElementDescriptor::NONE: |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 // Discard overly long attribute values to avoid DOS-ing the browser | 760 // Discard overly long attribute values to avoid DOS-ing the browser |
| 766 // process. However, send over a default string to indicate that the | 761 // process. However, send over a default string to indicate that the |
| 767 // attribute was present. | 762 // attribute was present. |
| 768 field->autocomplete_attribute = "x-max-data-length-exceeded"; | 763 field->autocomplete_attribute = "x-max-data-length-exceeded"; |
| 769 } | 764 } |
| 770 | 765 |
| 771 if (!IsAutofillableElement(element)) | 766 if (!IsAutofillableElement(element)) |
| 772 return; | 767 return; |
| 773 | 768 |
| 774 const WebInputElement* input_element = toWebInputElement(&element); | 769 const WebInputElement* input_element = toWebInputElement(&element); |
| 770 if (IsAutofillableInputElement(input_element) || | |
| 771 IsTextAreaElement(element)) { | |
| 772 field->is_autofilled = element.isAutofilled(); | |
| 773 field->is_focusable = element.isFocusable(); | |
| 774 field->should_autocomplete = element.autoComplete(); | |
| 775 field->text_direction = element.directionForFormData() == | |
| 776 "rtl" ? base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; | |
| 777 } | |
| 778 | |
| 775 if (IsAutofillableInputElement(input_element)) { | 779 if (IsAutofillableInputElement(input_element)) { |
| 776 if (IsTextInput(input_element)) | 780 if (IsTextInput(input_element)) |
| 777 field->max_length = input_element->maxLength(); | 781 field->max_length = input_element->maxLength(); |
| 778 | 782 |
| 779 field->is_autofilled = input_element->isAutofilled(); | |
| 780 field->is_focusable = input_element->isFocusable(); | |
| 781 field->is_checkable = IsCheckableElement(input_element); | 783 field->is_checkable = IsCheckableElement(input_element); |
| 782 field->is_checked = input_element->isChecked(); | 784 field->is_checked = input_element->isChecked(); |
| 783 field->should_autocomplete = input_element->autoComplete(); | |
| 784 field->text_direction = input_element->directionForFormData() == "rtl" ? | |
| 785 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; | |
| 786 } else if (IsTextAreaElement(element)) { | 785 } else if (IsTextAreaElement(element)) { |
| 787 // Nothing more to do in this case. | 786 // Nothing more to do in this case. |
| 788 } else if (extract_mask & EXTRACT_OPTIONS) { | 787 } else if (extract_mask & EXTRACT_OPTIONS) { |
| 789 // Set option strings on the field if available. | 788 // Set option strings on the field if available. |
| 790 DCHECK(IsSelectElement(element)); | 789 DCHECK(IsSelectElement(element)); |
| 791 const WebSelectElement select_element = element.toConst<WebSelectElement>(); | 790 const WebSelectElement select_element = element.toConst<WebSelectElement>(); |
| 792 GetOptionStringsFromElement(select_element, | 791 GetOptionStringsFromElement(select_element, |
| 793 &field->option_values, | 792 &field->option_values, |
| 794 &field->option_contents); | 793 &field->option_contents); |
| 795 } | 794 } |
| 796 | 795 |
| 797 if (!(extract_mask & EXTRACT_VALUE)) | 796 if (!(extract_mask & EXTRACT_VALUE)) |
| 798 return; | 797 return; |
| 799 | 798 |
| 800 base::string16 value; | 799 base::string16 value = element.value(); |
| 801 if (IsAutofillableInputElement(input_element)) { | 800 |
| 802 value = input_element->value(); | 801 if (IsSelectElement(element)) { |
| 803 } else if (IsTextAreaElement(element)) { | |
| 804 value = element.toConst<WebTextAreaElement>().value(); | |
| 805 } else { | |
| 806 DCHECK(IsSelectElement(element)); | |
| 807 const WebSelectElement select_element = element.toConst<WebSelectElement>(); | 802 const WebSelectElement select_element = element.toConst<WebSelectElement>(); |
| 808 value = select_element.value(); | |
| 809 | |
| 810 // Convert the |select_element| value to text if requested. | 803 // Convert the |select_element| value to text if requested. |
| 811 if (extract_mask & EXTRACT_OPTION_TEXT) { | 804 if (extract_mask & EXTRACT_OPTION_TEXT) { |
| 812 WebVector<WebElement> list_items = select_element.listItems(); | 805 WebVector<WebElement> list_items = select_element.listItems(); |
| 813 for (size_t i = 0; i < list_items.size(); ++i) { | 806 for (size_t i = 0; i < list_items.size(); ++i) { |
| 814 if (IsOptionElement(list_items[i])) { | 807 if (IsOptionElement(list_items[i])) { |
| 815 const WebOptionElement option_element = | 808 const WebOptionElement option_element = |
| 816 list_items[i].toConst<WebOptionElement>(); | 809 list_items[i].toConst<WebOptionElement>(); |
| 817 if (option_element.value() == value) { | 810 if (option_element.value() == value) { |
| 818 value = option_element.text(); | 811 value = option_element.text(); |
| 819 break; | 812 break; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 964 | 957 |
| 965 // Copy the created FormFields into the resulting FormData object. | 958 // Copy the created FormFields into the resulting FormData object. |
| 966 for (ScopedVector<FormFieldData>::const_iterator iter = form_fields.begin(); | 959 for (ScopedVector<FormFieldData>::const_iterator iter = form_fields.begin(); |
| 967 iter != form_fields.end(); ++iter) { | 960 iter != form_fields.end(); ++iter) { |
| 968 form->fields.push_back(**iter); | 961 form->fields.push_back(**iter); |
| 969 } | 962 } |
| 970 | 963 |
| 971 return true; | 964 return true; |
| 972 } | 965 } |
| 973 | 966 |
| 974 bool FindFormAndFieldForInputElement(const WebInputElement& element, | 967 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, |
| 975 FormData* form, | 968 FormData* form, |
| 976 FormFieldData* field, | 969 FormFieldData* field, |
| 977 RequirementsMask requirements) { | 970 RequirementsMask requirements) { |
| 978 if (!IsAutofillableElement(element)) | 971 if (!IsAutofillableElement(element)) |
| 979 return false; | 972 return false; |
| 980 | 973 |
| 981 const WebFormElement form_element = element.form(); | 974 const WebFormElement form_element = element.form(); |
| 982 if (form_element.isNull()) | 975 if (form_element.isNull()) |
| 983 return false; | 976 return false; |
| 984 | 977 |
| 985 ExtractMask extract_mask = | 978 ExtractMask extract_mask = |
| 986 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); | 979 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); |
| 987 return WebFormElementToFormData(form_element, | 980 return WebFormElementToFormData(form_element, |
| 988 element, | 981 element, |
| 989 requirements, | 982 requirements, |
| 990 extract_mask, | 983 extract_mask, |
| 991 form, | 984 form, |
| 992 field); | 985 field); |
| 993 } | 986 } |
| 994 | 987 |
| 995 void FillForm(const FormData& form, const WebInputElement& element) { | 988 void FillForm(const FormData& form, const WebFormControlElement& element) { |
| 996 WebFormElement form_element = element.form(); | 989 WebFormElement form_element = element.form(); |
| 997 if (form_element.isNull()) | 990 if (form_element.isNull()) |
| 998 return; | 991 return; |
| 999 | 992 |
| 1000 ForEachMatchingFormField(form_element, | 993 ForEachMatchingFormField(form_element, |
| 1001 element, | 994 element, |
| 1002 form, | 995 form, |
| 1003 FILTER_ALL_NON_EDITIABLE_ELEMENTS, | 996 FILTER_ALL_NON_EDITIABLE_ELEMENTS, |
| 1004 false, /* dont force override */ | 997 false, /* dont force override */ |
| 1005 &FillFormField); | 998 &FillFormField); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1026 return; | 1019 return; |
| 1027 | 1020 |
| 1028 ForEachMatchingFormField(form_element, | 1021 ForEachMatchingFormField(form_element, |
| 1029 WebInputElement(), | 1022 WebInputElement(), |
| 1030 form_data, | 1023 form_data, |
| 1031 FILTER_NONE, | 1024 FILTER_NONE, |
| 1032 true, /* force override */ | 1025 true, /* force override */ |
| 1033 &FillFormField); | 1026 &FillFormField); |
| 1034 } | 1027 } |
| 1035 | 1028 |
| 1036 void PreviewForm(const FormData& form, const WebInputElement& element) { | 1029 void PreviewForm(const FormData& form, const WebFormControlElement& element) { |
| 1037 WebFormElement form_element = element.form(); | 1030 WebFormElement form_element = element.form(); |
| 1038 if (form_element.isNull()) | 1031 if (form_element.isNull()) |
| 1039 return; | 1032 return; |
| 1040 | 1033 |
| 1041 ForEachMatchingFormField(form_element, | 1034 ForEachMatchingFormField(form_element, |
| 1042 element, | 1035 element, |
| 1043 form, | 1036 form, |
| 1044 FILTER_ALL_NON_EDITIABLE_ELEMENTS, | 1037 FILTER_ALL_NON_EDITIABLE_ELEMENTS, |
| 1045 false, /* dont force override */ | 1038 false, /* dont force override */ |
| 1046 &PreviewFormField); | 1039 &PreviewFormField); |
| 1047 } | 1040 } |
| 1048 | 1041 |
| 1049 bool ClearPreviewedFormWithElement(const WebInputElement& element, | 1042 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, |
| 1050 bool was_autofilled) { | 1043 bool was_autofilled) { |
| 1051 WebFormElement form_element = element.form(); | 1044 WebFormElement form_element = element.form(); |
| 1052 if (form_element.isNull()) | 1045 if (form_element.isNull()) |
| 1053 return false; | 1046 return false; |
| 1054 | 1047 |
| 1055 std::vector<WebFormControlElement> control_elements; | 1048 std::vector<WebFormControlElement> control_elements; |
| 1056 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE, | 1049 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE, |
| 1057 &control_elements); | 1050 &control_elements); |
| 1058 for (size_t i = 0; i < control_elements.size(); ++i) { | 1051 for (size_t i = 0; i < control_elements.size(); ++i) { |
| 1059 // There might be unrelated elements in this form which have already been | 1052 // There might be unrelated elements in this form which have already been |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1072 // If the element is not auto-filled, we did not preview it, | 1065 // If the element is not auto-filled, we did not preview it, |
| 1073 // so there is nothing to reset. | 1066 // so there is nothing to reset. |
| 1074 if(!control_element.isAutofilled()) | 1067 if(!control_element.isAutofilled()) |
| 1075 continue; | 1068 continue; |
| 1076 | 1069 |
| 1077 if ((IsTextInput(input_element) && | 1070 if ((IsTextInput(input_element) && |
| 1078 input_element->suggestedValue().isEmpty()) || | 1071 input_element->suggestedValue().isEmpty()) || |
| 1079 (IsMonthInput(input_element) && | 1072 (IsMonthInput(input_element) && |
| 1080 input_element->suggestedValue().isEmpty()) || | 1073 input_element->suggestedValue().isEmpty()) || |
| 1081 (IsTextAreaElement(control_element) && | 1074 (IsTextAreaElement(control_element) && |
| 1082 control_element.to<WebTextAreaElement>().suggestedValue().isEmpty())) | 1075 control_element.suggestedValue().isEmpty())) |
|
Ilya Sherman
2014/03/14 07:24:46
nit: Can this be shortened to the following?
if (
ziran.sun
2014/03/14 17:01:42
Done.
| |
| 1083 continue; | 1076 continue; |
| 1084 | 1077 |
| 1085 // Clear the suggested value. For the initiating node, also restore the | 1078 // Clear the suggested value. For the initiating node, also restore the |
| 1086 // original value. | 1079 // original value. |
| 1080 bool is_initiating_node = false; | |
|
Ilya Sherman
2014/03/14 07:24:46
nit: Can the logic be extracted out to here as "bo
ziran.sun
2014/03/14 17:01:42
Done.
| |
| 1087 if (IsTextInput(input_element) || IsMonthInput(input_element)) { | 1081 if (IsTextInput(input_element) || IsMonthInput(input_element)) { |
| 1088 input_element->setSuggestedValue(WebString()); | 1082 input_element->setSuggestedValue(WebString()); |
| 1089 bool is_initiating_node = (element == *input_element); | 1083 is_initiating_node = (element == *input_element); |
| 1090 if (is_initiating_node) | 1084 if (is_initiating_node) |
| 1091 input_element->setAutofilled(was_autofilled); | 1085 input_element->setAutofilled(was_autofilled); |
| 1092 else | 1086 else |
| 1093 input_element->setAutofilled(false); | 1087 input_element->setAutofilled(false); |
|
Ilya Sherman
2014/03/14 07:24:46
nit: Please share these four lines between input e
ziran.sun
2014/03/14 17:01:42
Done.
| |
| 1094 | |
| 1095 // Clearing the suggested value in the focused node (above) can cause | |
| 1096 // selection to be lost. We force selection range to restore the text | |
| 1097 // cursor. | |
| 1098 if (is_initiating_node) { | |
| 1099 int length = input_element->value().length(); | |
| 1100 input_element->setSelectionRange(length, length); | |
| 1101 } | |
| 1102 } else if (IsTextAreaElement(control_element)) { | 1088 } else if (IsTextAreaElement(control_element)) { |
| 1103 WebTextAreaElement text_area = control_element.to<WebTextAreaElement>(); | 1089 control_element.setSuggestedValue(WebString()); |
| 1104 text_area.setSuggestedValue(WebString()); | 1090 is_initiating_node = (element == control_element); |
| 1105 bool is_initiating_node = (element == text_area); | |
| 1106 if (is_initiating_node) | 1091 if (is_initiating_node) |
| 1107 control_element.setAutofilled(was_autofilled); | 1092 control_element.setAutofilled(was_autofilled); |
| 1108 else | 1093 else |
| 1109 control_element.setAutofilled(false); | 1094 control_element.setAutofilled(false); |
| 1110 } | 1095 } |
| 1096 | |
| 1097 // Clearing the suggested value in the focused node (above) can cause | |
| 1098 // selection to be lost. We force selection range to restore the text | |
| 1099 // cursor. | |
| 1100 if (is_initiating_node) { | |
| 1101 int length = control_element.value().length(); | |
| 1102 control_element.setSelectionRange(length, length); | |
| 1103 } | |
| 1111 } | 1104 } |
| 1112 | 1105 |
| 1113 return true; | 1106 return true; |
| 1114 } | 1107 } |
| 1115 | 1108 |
| 1116 bool FormWithElementIsAutofilled(const WebInputElement& element) { | 1109 bool FormWithElementIsAutofilled(const WebInputElement& element) { |
| 1117 WebFormElement form_element = element.form(); | 1110 WebFormElement form_element = element.form(); |
| 1118 if (form_element.isNull()) | 1111 if (form_element.isNull()) |
| 1119 return false; | 1112 return false; |
| 1120 | 1113 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1177 tag_is_allowed = true; | 1170 tag_is_allowed = true; |
| 1178 break; | 1171 break; |
| 1179 } | 1172 } |
| 1180 } | 1173 } |
| 1181 if (!tag_is_allowed) | 1174 if (!tag_is_allowed) |
| 1182 return false; | 1175 return false; |
| 1183 } | 1176 } |
| 1184 return true; | 1177 return true; |
| 1185 } | 1178 } |
| 1186 | 1179 |
| 1187 gfx::RectF GetScaledBoundingBox(float scale, WebInputElement* element) { | 1180 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { |
| 1188 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1181 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
| 1189 return gfx::RectF(bounding_box.x() * scale, | 1182 return gfx::RectF(bounding_box.x() * scale, |
| 1190 bounding_box.y() * scale, | 1183 bounding_box.y() * scale, |
| 1191 bounding_box.width() * scale, | 1184 bounding_box.width() * scale, |
| 1192 bounding_box.height() * scale); | 1185 bounding_box.height() * scale); |
| 1193 } | 1186 } |
| 1194 | 1187 |
| 1195 } // namespace autofill | 1188 } // namespace autofill |
| OLD | NEW |