Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: components/autofill/content/renderer/form_autofill_util.cc

Issue 140093005: Add supports that allow Autofill to be initiated from textarea field (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update code as per Ilya's 3rd set of review comments - all comments addressed Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 431
432 // If we didn't find a label, check for definition list case. 432 // If we didn't find a label, check for definition list case.
433 inferred_label = InferLabelFromDefinitionList(element); 433 inferred_label = InferLabelFromDefinitionList(element);
434 if (!inferred_label.empty()) 434 if (!inferred_label.empty())
435 return inferred_label; 435 return inferred_label;
436 436
437 // If we didn't find a label, check for div table case. 437 // If we didn't find a label, check for div table case.
438 return InferLabelFromDivTable(element); 438 return InferLabelFromDivTable(element);
439 } 439 }
440 440
441 // A simple wrapper to get an element's value.
442 WebString GetValue(const WebFormControlElement& element) {
443 const WebInputElement* input_element = toWebInputElement(&element);
444 if (IsAutofillableInputElement(input_element))
445 return input_element->value();
446
447 if (IsTextAreaElement(element))
448 return element.toConst<WebTextAreaElement>().value();
449
450 DCHECK(IsSelectElement(element));
451 return element.toConst<WebSelectElement>().value();
452 }
453
454 // A simple wrapper to get an element's suggested value.
455 WebString GetSuggestedValue(const WebFormControlElement& element) {
456 const WebInputElement* input_element = toWebInputElement(&element);
457 if (IsAutofillableInputElement(input_element))
458 return input_element->suggestedValue();
459
460 DCHECK(IsTextAreaElement(element));
461 return element.toConst<WebTextAreaElement>().suggestedValue();
462 }
463
464 // A simple wrapper to get an element's character selection range.
465 void SetSelectionRange(WebFormControlElement element, int start, int end) {
466 WebInputElement* input_element = toWebInputElement(&element);
467 if (IsAutofillableInputElement(input_element)) {
468 input_element->setSelectionRange(start, end);
469 } else {
470 DCHECK(IsTextAreaElement(element));
471 element.to<WebTextAreaElement>().setSelectionRange(start, end);
472 }
473 }
474
475 // A helper function to set common attributes shared among elements.
476 void SetCommonAttributes(const WebFormControlElement& element,
477 FormFieldData* field) {
478 const WebInputElement* input_element = toWebInputElement(&element);
479 if (!IsAutofillableInputElement(input_element) &&
480 !IsTextAreaElement(element))
481 return;
482
483 field->is_autofilled = element.isAutofilled();
484 field->is_focusable = element.isFocusable();
485 if (IsAutofillableInputElement(input_element)) {
486 field->should_autocomplete = input_element->autoComplete();
487 field->text_direction = input_element->directionForFormData() ==
488 "rtl" ? base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT;
489 } else {
490 DCHECK(IsTextAreaElement(element));
491 const WebTextAreaElement textarea_element =
492 element.toConst<WebTextAreaElement>();
493 field->should_autocomplete = textarea_element.autoComplete();
494 field->text_direction = textarea_element.directionForFormData() ==
495 "rtl" ? base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT;
496 }
497 }
498
441 // Fills |option_strings| with the values of the <option> elements present in 499 // Fills |option_strings| with the values of the <option> elements present in
442 // |select_element|. 500 // |select_element|.
443 void GetOptionStringsFromElement(const WebSelectElement& select_element, 501 void GetOptionStringsFromElement(const WebSelectElement& select_element,
444 std::vector<base::string16>* option_values, 502 std::vector<base::string16>* option_values,
445 std::vector<base::string16>* option_contents) { 503 std::vector<base::string16>* option_contents) {
446 DCHECK(!select_element.isNull()); 504 DCHECK(!select_element.isNull());
447 505
448 option_values->clear(); 506 option_values->clear();
449 option_contents->clear(); 507 option_contents->clear();
450 WebVector<WebElement> list_items = select_element.listItems(); 508 WebVector<WebElement> list_items = select_element.listItems();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 return; 590 return;
533 591
534 field->setAutofilled(true); 592 field->setAutofilled(true);
535 593
536 WebInputElement* input_element = toWebInputElement(field); 594 WebInputElement* input_element = toWebInputElement(field);
537 if (IsTextInput(input_element) || IsMonthInput(input_element)) { 595 if (IsTextInput(input_element) || IsMonthInput(input_element)) {
538 // If the maxlength attribute contains a negative value, maxLength() 596 // If the maxlength attribute contains a negative value, maxLength()
539 // returns the default maxlength value. 597 // returns the default maxlength value.
540 input_element->setValue( 598 input_element->setValue(
541 data.value.substr(0, input_element->maxLength()), true); 599 data.value.substr(0, input_element->maxLength()), true);
542 if (is_initiating_node) {
543 int length = input_element->value().length();
544 input_element->setSelectionRange(length, length);
545 // Clear the current IME composition (the underline), if there is one.
546 input_element->document().frame()->unmarkText();
547 }
548 } else if (IsTextAreaElement(*field)) { 600 } else if (IsTextAreaElement(*field)) {
549 WebTextAreaElement text_area = field->to<WebTextAreaElement>(); 601 WebTextAreaElement text_area = field->to<WebTextAreaElement>();
550 if (text_area.value() != data.value) { 602 if (text_area.value() != data.value) {
551 text_area.setValue(data.value); 603 text_area.setValue(data.value);
552 text_area.dispatchFormControlChangeEvent(); 604 text_area.dispatchFormControlChangeEvent();
553 } 605 }
554 } else if (IsSelectElement(*field)) { 606 } else if (IsSelectElement(*field)) {
555 WebSelectElement select_element = field->to<WebSelectElement>(); 607 WebSelectElement select_element = field->to<WebSelectElement>();
556 if (select_element.value() != data.value) { 608 if (select_element.value() != data.value) {
557 select_element.setValue(data.value); 609 select_element.setValue(data.value);
558 select_element.dispatchFormControlChangeEvent(); 610 select_element.dispatchFormControlChangeEvent();
559 } 611 }
560 } else { 612 } else {
561 DCHECK(IsCheckableElement(input_element)); 613 DCHECK(IsCheckableElement(input_element));
562 input_element->setChecked(data.is_checked, true); 614 input_element->setChecked(data.is_checked, true);
563 } 615 }
616
617 if (is_initiating_node &&
618 ((IsTextInput(input_element) || IsMonthInput(input_element)) ||
619 IsTextAreaElement(*field))) {
620 int length = GetValue(*field).length();
621 SetSelectionRange(*field, length, length);
622 // Clear the current IME composition (the underline), if there is one.
623 field->document().frame()->unmarkText();
624 }
564 } 625 }
565 626
566 // Sets the |field|'s "suggested" (non JS visible) value to the value in |data|. 627 // 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. 628 // Also sets the "autofilled" attribute, causing the background to be yellow.
568 void PreviewFormField(const FormFieldData& data, 629 void PreviewFormField(const FormFieldData& data,
569 bool is_initiating_node, 630 bool is_initiating_node,
570 blink::WebFormControlElement* field) { 631 blink::WebFormControlElement* field) {
571 // Nothing to preview. 632 // Nothing to preview.
572 if (data.value.empty()) 633 if (data.value.empty())
573 return; 634 return;
574 635
575 // Preview input and textarea fields. For input fields, excludes checkboxes 636 // Preview input and textarea fields. For input fields, excludes checkboxes
576 // and radio buttons, as there is no provision for setSuggestedCheckedValue 637 // and radio buttons, as there is no provision for setSuggestedCheckedValue
577 // in WebInputElement. 638 // in WebInputElement.
578 WebInputElement* input_element = toWebInputElement(field); 639 WebInputElement* input_element = toWebInputElement(field);
579 if (IsTextInput(input_element)) { 640 if (IsTextInput(input_element)) {
580 // If the maxlength attribute contains a negative value, maxLength() 641 // If the maxlength attribute contains a negative value, maxLength()
581 // returns the default maxlength value. 642 // returns the default maxlength value.
582 input_element->setSuggestedValue( 643 input_element->setSuggestedValue(
583 data.value.substr(0, input_element->maxLength())); 644 data.value.substr(0, input_element->maxLength()));
584 input_element->setAutofilled(true); 645 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)) { 646 } else if (IsTextAreaElement(*field)) {
592 WebTextAreaElement textarea = field->to<WebTextAreaElement>(); 647 WebTextAreaElement textarea = field->to<WebTextAreaElement>();
593 textarea.setSuggestedValue(data.value); 648 textarea.setSuggestedValue(data.value);
594 field->setAutofilled(true); 649 field->setAutofilled(true);
595 } 650 }
651
652 if (is_initiating_node &&
653 (IsTextInput(input_element) || IsTextAreaElement(*field))) {
654 // Select the part of the text that the user didn't type.
655 int start = GetValue(*field).length();
656 int end = GetSuggestedValue(*field).length();
657 SetSelectionRange(*field, start, end);
658 }
596 } 659 }
597 660
598 std::string RetrievalMethodToString( 661 std::string RetrievalMethodToString(
599 const WebElementDescriptor::RetrievalMethod& method) { 662 const WebElementDescriptor::RetrievalMethod& method) {
600 switch (method) { 663 switch (method) {
601 case WebElementDescriptor::CSS_SELECTOR: 664 case WebElementDescriptor::CSS_SELECTOR:
602 return "CSS_SELECTOR"; 665 return "CSS_SELECTOR";
603 case WebElementDescriptor::ID: 666 case WebElementDescriptor::ID:
604 return "ID"; 667 return "ID";
605 case WebElementDescriptor::NONE: 668 case WebElementDescriptor::NONE:
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 if (field->autocomplete_attribute.size() > kMaxDataLength) { 827 if (field->autocomplete_attribute.size() > kMaxDataLength) {
765 // Discard overly long attribute values to avoid DOS-ing the browser 828 // Discard overly long attribute values to avoid DOS-ing the browser
766 // process. However, send over a default string to indicate that the 829 // process. However, send over a default string to indicate that the
767 // attribute was present. 830 // attribute was present.
768 field->autocomplete_attribute = "x-max-data-length-exceeded"; 831 field->autocomplete_attribute = "x-max-data-length-exceeded";
769 } 832 }
770 833
771 if (!IsAutofillableElement(element)) 834 if (!IsAutofillableElement(element))
772 return; 835 return;
773 836
837 SetCommonAttributes(element, field);
838
774 const WebInputElement* input_element = toWebInputElement(&element); 839 const WebInputElement* input_element = toWebInputElement(&element);
775 if (IsAutofillableInputElement(input_element)) { 840 if (IsAutofillableInputElement(input_element)) {
776 if (IsTextInput(input_element)) 841 if (IsTextInput(input_element))
777 field->max_length = input_element->maxLength(); 842 field->max_length = input_element->maxLength();
778 843
779 field->is_autofilled = input_element->isAutofilled();
780 field->is_focusable = input_element->isFocusable();
781 field->is_checkable = IsCheckableElement(input_element); 844 field->is_checkable = IsCheckableElement(input_element);
782 field->is_checked = input_element->isChecked(); 845 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)) { 846 } else if (IsTextAreaElement(element)) {
787 // Nothing more to do in this case. 847 // Nothing more to do in this case.
788 } else if (extract_mask & EXTRACT_OPTIONS) { 848 } else if (extract_mask & EXTRACT_OPTIONS) {
789 // Set option strings on the field if available. 849 // Set option strings on the field if available.
790 DCHECK(IsSelectElement(element)); 850 DCHECK(IsSelectElement(element));
791 const WebSelectElement select_element = element.toConst<WebSelectElement>(); 851 const WebSelectElement select_element = element.toConst<WebSelectElement>();
792 GetOptionStringsFromElement(select_element, 852 GetOptionStringsFromElement(select_element,
793 &field->option_values, 853 &field->option_values,
794 &field->option_contents); 854 &field->option_contents);
795 } 855 }
796 856
797 if (!(extract_mask & EXTRACT_VALUE)) 857 if (!(extract_mask & EXTRACT_VALUE))
798 return; 858 return;
799 859
800 base::string16 value; 860 base::string16 value = GetValue(element);
801 if (IsAutofillableInputElement(input_element)) { 861
802 value = input_element->value(); 862 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>(); 863 const WebSelectElement select_element = element.toConst<WebSelectElement>();
808 value = select_element.value();
809
810 // Convert the |select_element| value to text if requested. 864 // Convert the |select_element| value to text if requested.
811 if (extract_mask & EXTRACT_OPTION_TEXT) { 865 if (extract_mask & EXTRACT_OPTION_TEXT) {
812 WebVector<WebElement> list_items = select_element.listItems(); 866 WebVector<WebElement> list_items = select_element.listItems();
813 for (size_t i = 0; i < list_items.size(); ++i) { 867 for (size_t i = 0; i < list_items.size(); ++i) {
814 if (IsOptionElement(list_items[i])) { 868 if (IsOptionElement(list_items[i])) {
815 const WebOptionElement option_element = 869 const WebOptionElement option_element =
816 list_items[i].toConst<WebOptionElement>(); 870 list_items[i].toConst<WebOptionElement>();
817 if (option_element.value() == value) { 871 if (option_element.value() == value) {
818 value = option_element.text(); 872 value = option_element.text();
819 break; 873 break;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 1018
965 // Copy the created FormFields into the resulting FormData object. 1019 // Copy the created FormFields into the resulting FormData object.
966 for (ScopedVector<FormFieldData>::const_iterator iter = form_fields.begin(); 1020 for (ScopedVector<FormFieldData>::const_iterator iter = form_fields.begin();
967 iter != form_fields.end(); ++iter) { 1021 iter != form_fields.end(); ++iter) {
968 form->fields.push_back(**iter); 1022 form->fields.push_back(**iter);
969 } 1023 }
970 1024
971 return true; 1025 return true;
972 } 1026 }
973 1027
974 bool FindFormAndFieldForInputElement(const WebInputElement& element, 1028 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element,
975 FormData* form, 1029 FormData* form,
976 FormFieldData* field, 1030 FormFieldData* field,
977 RequirementsMask requirements) { 1031 RequirementsMask requirements) {
978 if (!IsAutofillableElement(element)) 1032 if (!IsAutofillableElement(element))
979 return false; 1033 return false;
980 1034
981 const WebFormElement form_element = element.form(); 1035 const WebFormElement form_element = element.form();
982 if (form_element.isNull()) 1036 if (form_element.isNull())
983 return false; 1037 return false;
984 1038
985 ExtractMask extract_mask = 1039 ExtractMask extract_mask =
986 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); 1040 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
987 return WebFormElementToFormData(form_element, 1041 return WebFormElementToFormData(form_element,
988 element, 1042 element,
989 requirements, 1043 requirements,
990 extract_mask, 1044 extract_mask,
991 form, 1045 form,
992 field); 1046 field);
993 } 1047 }
994 1048
995 void FillForm(const FormData& form, const WebInputElement& element) { 1049 void FillForm(const FormData& form, const WebFormControlElement& element) {
996 WebFormElement form_element = element.form(); 1050 WebFormElement form_element = element.form();
997 if (form_element.isNull()) 1051 if (form_element.isNull())
998 return; 1052 return;
999 1053
1000 ForEachMatchingFormField(form_element, 1054 ForEachMatchingFormField(form_element,
1001 element, 1055 element,
1002 form, 1056 form,
1003 FILTER_ALL_NON_EDITIABLE_ELEMENTS, 1057 FILTER_ALL_NON_EDITIABLE_ELEMENTS,
1004 false, /* dont force override */ 1058 false, /* dont force override */
1005 &FillFormField); 1059 &FillFormField);
(...skipping 20 matching lines...) Expand all
1026 return; 1080 return;
1027 1081
1028 ForEachMatchingFormField(form_element, 1082 ForEachMatchingFormField(form_element,
1029 WebInputElement(), 1083 WebInputElement(),
1030 form_data, 1084 form_data,
1031 FILTER_NONE, 1085 FILTER_NONE,
1032 true, /* force override */ 1086 true, /* force override */
1033 &FillFormField); 1087 &FillFormField);
1034 } 1088 }
1035 1089
1036 void PreviewForm(const FormData& form, const WebInputElement& element) { 1090 void PreviewForm(const FormData& form, const WebFormControlElement& element) {
1037 WebFormElement form_element = element.form(); 1091 WebFormElement form_element = element.form();
1038 if (form_element.isNull()) 1092 if (form_element.isNull())
1039 return; 1093 return;
1040 1094
1041 ForEachMatchingFormField(form_element, 1095 ForEachMatchingFormField(form_element,
1042 element, 1096 element,
1043 form, 1097 form,
1044 FILTER_ALL_NON_EDITIABLE_ELEMENTS, 1098 FILTER_ALL_NON_EDITIABLE_ELEMENTS,
1045 false, /* dont force override */ 1099 false, /* dont force override */
1046 &PreviewFormField); 1100 &PreviewFormField);
1047 } 1101 }
1048 1102
1049 bool ClearPreviewedFormWithElement(const WebInputElement& element, 1103 bool ClearPreviewedFormWithElement(const WebFormControlElement& element,
1050 bool was_autofilled) { 1104 bool was_autofilled) {
1051 WebFormElement form_element = element.form(); 1105 WebFormElement form_element = element.form();
1052 if (form_element.isNull()) 1106 if (form_element.isNull())
1053 return false; 1107 return false;
1054 1108
1055 std::vector<WebFormControlElement> control_elements; 1109 std::vector<WebFormControlElement> control_elements;
1056 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE, 1110 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE,
1057 &control_elements); 1111 &control_elements);
1058 for (size_t i = 0; i < control_elements.size(); ++i) { 1112 for (size_t i = 0; i < control_elements.size(); ++i) {
1059 // There might be unrelated elements in this form which have already been 1113 // There might be unrelated elements in this form which have already been
(...skipping 13 matching lines...) Expand all
1073 continue; 1127 continue;
1074 1128
1075 if ((IsTextInput(input_element) && 1129 if ((IsTextInput(input_element) &&
1076 input_element->suggestedValue().isEmpty()) || 1130 input_element->suggestedValue().isEmpty()) ||
1077 (IsTextAreaElement(control_element) && 1131 (IsTextAreaElement(control_element) &&
1078 control_element.to<WebTextAreaElement>().suggestedValue().isEmpty())) 1132 control_element.to<WebTextAreaElement>().suggestedValue().isEmpty()))
1079 continue; 1133 continue;
1080 1134
1081 // Clear the suggested value. For the initiating node, also restore the 1135 // Clear the suggested value. For the initiating node, also restore the
1082 // original value. 1136 // original value.
1137 bool is_initiating_node;
Ilya Sherman 2014/03/01 02:50:53 Please make sure to initialize this variable here,
ziran.sun 2014/03/03 19:23:32 Done.
1083 if (IsTextInput(input_element)) { 1138 if (IsTextInput(input_element)) {
1084 input_element->setSuggestedValue(WebString()); 1139 input_element->setSuggestedValue(WebString());
1085 bool is_initiating_node = (element == *input_element); 1140 is_initiating_node = (element == *input_element);
1086 if (is_initiating_node) 1141 if (is_initiating_node)
1087 input_element->setAutofilled(was_autofilled); 1142 input_element->setAutofilled(was_autofilled);
1088 else 1143 else
1089 input_element->setAutofilled(false); 1144 input_element->setAutofilled(false);
1090
1091 // Clearing the suggested value in the focused node (above) can cause
1092 // selection to be lost. We force selection range to restore the text
1093 // cursor.
1094 if (is_initiating_node) {
1095 int length = input_element->value().length();
1096 input_element->setSelectionRange(length, length);
1097 }
1098 } else if (IsTextAreaElement(control_element)) { 1145 } else if (IsTextAreaElement(control_element)) {
1099 WebTextAreaElement text_area = control_element.to<WebTextAreaElement>(); 1146 WebTextAreaElement text_area = control_element.to<WebTextAreaElement>();
1100 text_area.setSuggestedValue(WebString()); 1147 text_area.setSuggestedValue(WebString());
1101 bool is_initiating_node = (element == text_area); 1148 is_initiating_node = (element == text_area);
1102 if (is_initiating_node) 1149 if (is_initiating_node)
1103 control_element.setAutofilled(was_autofilled); 1150 control_element.setAutofilled(was_autofilled);
1104 else 1151 else
1105 control_element.setAutofilled(false); 1152 control_element.setAutofilled(false);
1106 } 1153 }
1154
1155 // Clearing the suggested value in the focused node (above) can cause
1156 // selection to be lost. We force selection range to restore the text
1157 // cursor.
1158 if (is_initiating_node) {
1159 int length = GetValue(control_element).length();
1160 SetSelectionRange(control_element, length, length);
1161 }
1107 } 1162 }
1108 1163
1109 return true; 1164 return true;
1110 } 1165 }
1111 1166
1112 bool FormWithElementIsAutofilled(const WebInputElement& element) { 1167 bool FormWithElementIsAutofilled(const WebInputElement& element) {
1113 WebFormElement form_element = element.form(); 1168 WebFormElement form_element = element.form();
1114 if (form_element.isNull()) 1169 if (form_element.isNull())
1115 return false; 1170 return false;
1116 1171
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 tag_is_allowed = true; 1227 tag_is_allowed = true;
1173 break; 1228 break;
1174 } 1229 }
1175 } 1230 }
1176 if (!tag_is_allowed) 1231 if (!tag_is_allowed)
1177 return false; 1232 return false;
1178 } 1233 }
1179 return true; 1234 return true;
1180 } 1235 }
1181 1236
1182 gfx::RectF GetScaledBoundingBox(float scale, WebInputElement* element) { 1237 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) {
1183 gfx::Rect bounding_box(element->boundsInViewportSpace()); 1238 gfx::Rect bounding_box(element->boundsInViewportSpace());
1184 return gfx::RectF(bounding_box.x() * scale, 1239 return gfx::RectF(bounding_box.x() * scale,
1185 bounding_box.y() * scale, 1240 bounding_box.y() * scale,
1186 bounding_box.width() * scale, 1241 bounding_box.width() * scale,
1187 bounding_box.height() * scale); 1242 bounding_box.height() * scale);
1188 } 1243 }
1189 1244
1190 } // namespace autofill 1245 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698