OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/renderer/autofill/form_cache.h" | 5 #include "chrome/renderer/autofill/form_cache.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
9 #include "chrome/common/form_data.h" | 9 #include "chrome/common/form_data.h" |
10 #include "chrome/common/form_data_predictions.h" | 10 #include "chrome/common/form_data_predictions.h" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 // The number of fields required by Autofill. Ideally we could send the forms | 36 // The number of fields required by Autofill. Ideally we could send the forms |
37 // to Autofill no matter how many fields are in the forms; however, finding the | 37 // to Autofill no matter how many fields are in the forms; however, finding the |
38 // label for each field is a costly operation and we can't spare the cycles if | 38 // label for each field is a costly operation and we can't spare the cycles if |
39 // it's not necessary. | 39 // it's not necessary. |
40 const size_t kRequiredAutofillFields = 3; | 40 const size_t kRequiredAutofillFields = 3; |
41 | 41 |
42 } // namespace | 42 } // namespace |
43 | 43 |
44 namespace autofill { | 44 namespace autofill { |
45 | 45 |
46 // Helper function to discard state of various WebFormElements when they go out | |
47 // of web frame's scope. | |
Ilya Sherman
2012/12/12 00:26:44
nit: Perhaps mention that this is done so as to re
Raman Kakilate
2012/12/12 01:22:04
Done.
Raman Kakilate
2012/12/12 01:22:04
Done.
| |
48 // K should inherit from WebFormControlElement as the function looks to extract | |
49 // WebFormElement for K.form(). | |
50 template <class K, class V> | |
51 void RemoveOldElements(const WebFrame& frame, std::map<const K, V>* states) { | |
52 std::vector<K> to_remove; | |
53 for (typename std::map<const K, V>::const_iterator it = states->begin(); | |
54 it != states->end(); ++it) { | |
55 WebFormElement form_element = it->first.form(); | |
56 if (form_element.isNull()) { | |
57 to_remove.push_back(it->first); | |
58 } else { | |
59 const WebFrame* element_frame = form_element.document().frame(); | |
60 if (!element_frame || element_frame == &frame) | |
61 to_remove.push_back(it->first); | |
62 } | |
63 } | |
64 | |
65 for (typename std::vector<K>::const_iterator it = to_remove.begin(); | |
66 it != to_remove.end(); ++it) { | |
67 states->erase(*it); | |
68 } | |
69 } | |
70 | |
46 FormCache::FormCache() { | 71 FormCache::FormCache() { |
47 } | 72 } |
48 | 73 |
49 FormCache::~FormCache() { | 74 FormCache::~FormCache() { |
50 } | 75 } |
51 | 76 |
52 void FormCache::ExtractForms(const WebFrame& frame, | 77 void FormCache::ExtractForms(const WebFrame& frame, |
53 std::vector<FormData>* forms) { | 78 std::vector<FormData>* forms) { |
54 // Reset the cache for this frame. | 79 // Reset the cache for this frame. |
55 ResetFrame(frame); | 80 ResetFrame(frame); |
(...skipping 17 matching lines...) Expand all Loading... | |
73 for (size_t j = 0; j < control_elements.size(); ++j) { | 98 for (size_t j = 0; j < control_elements.size(); ++j) { |
74 WebFormControlElement element = control_elements[j]; | 99 WebFormControlElement element = control_elements[j]; |
75 | 100 |
76 // Save original values of <select> elements so we can restore them | 101 // Save original values of <select> elements so we can restore them |
77 // when |ClearFormWithNode()| is invoked. | 102 // when |ClearFormWithNode()| is invoked. |
78 if (IsSelectElement(element)) { | 103 if (IsSelectElement(element)) { |
79 const WebSelectElement select_element = | 104 const WebSelectElement select_element = |
80 element.toConst<WebSelectElement>(); | 105 element.toConst<WebSelectElement>(); |
81 initial_select_values_.insert(std::make_pair(select_element, | 106 initial_select_values_.insert(std::make_pair(select_element, |
82 select_element.value())); | 107 select_element.value())); |
108 } else { | |
109 const WebInputElement input_element = | |
110 element.toConst<WebInputElement>(); | |
111 if (IsRadioButtonElement(&input_element) || | |
112 IsCheckboxElement(&input_element)) | |
113 initial_checked_state_.insert( | |
114 std::make_pair(input_element, input_element.isChecked())); | |
83 } | 115 } |
84 } | 116 } |
85 | 117 |
86 // To avoid overly expensive computation, we impose a minimum number of | 118 // To avoid overly expensive computation, we impose a minimum number of |
87 // allowable fields. The corresponding maximum number of allowable fields | 119 // allowable fields. The corresponding maximum number of allowable fields |
88 // is imposed by WebFormElementToFormData(). | 120 // is imposed by WebFormElementToFormData(). |
89 if (control_elements.size() < kRequiredAutofillFields) | 121 if (control_elements.size() < kRequiredAutofillFields) |
90 continue; | 122 continue; |
91 | 123 |
92 FormData form; | 124 FormData form; |
(...skipping 19 matching lines...) Expand all Loading... | |
112 if (!document_frame || document_frame == &frame) | 144 if (!document_frame || document_frame == &frame) |
113 documents_to_delete.push_back(*it); | 145 documents_to_delete.push_back(*it); |
114 } | 146 } |
115 | 147 |
116 for (std::vector<WebDocument>::const_iterator it = | 148 for (std::vector<WebDocument>::const_iterator it = |
117 documents_to_delete.begin(); | 149 documents_to_delete.begin(); |
118 it != documents_to_delete.end(); ++it) { | 150 it != documents_to_delete.end(); ++it) { |
119 web_documents_.erase(*it); | 151 web_documents_.erase(*it); |
120 } | 152 } |
121 | 153 |
122 std::vector<WebSelectElement> select_values_to_delete; | 154 RemoveOldElements(frame, &initial_select_values_); |
123 for (std::map<const WebSelectElement, string16>::const_iterator it = | 155 RemoveOldElements(frame, &initial_checked_state_); |
124 initial_select_values_.begin(); | |
125 it != initial_select_values_.end(); ++it) { | |
126 WebFormElement form_element = it->first.form(); | |
127 if (form_element.isNull()) { | |
128 select_values_to_delete.push_back(it->first); | |
129 } else { | |
130 const WebFrame* element_frame = form_element.document().frame(); | |
131 if (!element_frame || element_frame == &frame) | |
132 select_values_to_delete.push_back(it->first); | |
133 } | |
134 } | |
135 | |
136 for (std::vector<WebSelectElement>::const_iterator it = | |
137 select_values_to_delete.begin(); | |
138 it != select_values_to_delete.end(); ++it) { | |
139 initial_select_values_.erase(*it); | |
140 } | |
141 } | 156 } |
142 | 157 |
143 bool FormCache::ClearFormWithElement(const WebInputElement& element) { | 158 bool FormCache::ClearFormWithElement(const WebInputElement& element) { |
144 WebFormElement form_element = element.form(); | 159 WebFormElement form_element = element.form(); |
145 if (form_element.isNull()) | 160 if (form_element.isNull()) |
146 return false; | 161 return false; |
147 | 162 |
148 std::vector<WebFormControlElement> control_elements; | 163 std::vector<WebFormControlElement> control_elements; |
149 ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, | 164 ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, |
150 &control_elements); | 165 &control_elements); |
151 for (size_t i = 0; i < control_elements.size(); ++i) { | 166 for (size_t i = 0; i < control_elements.size(); ++i) { |
152 WebFormControlElement control_element = control_elements[i]; | 167 WebFormControlElement control_element = control_elements[i]; |
153 WebInputElement* input_element = toWebInputElement(&control_element); | 168 WebInputElement* input_element = toWebInputElement(&control_element); |
154 if (IsTextInput(input_element)) { | 169 if (IsTextInput(input_element)) { |
155 // We don't modify the value of disabled fields. | 170 // We don't modify the value of disabled fields. |
156 if (!input_element->isEnabled()) | 171 if (!input_element->isEnabled()) |
157 continue; | 172 continue; |
158 | 173 |
159 input_element->setValue(string16(), true); | 174 input_element->setValue(string16(), true); |
160 input_element->setAutofilled(false); | 175 input_element->setAutofilled(false); |
161 | 176 |
162 // Clearing the value in the focused node (above) can cause selection | 177 // Clearing the value in the focused node (above) can cause selection |
163 // to be lost. We force selection range to restore the text cursor. | 178 // to be lost. We force selection range to restore the text cursor. |
164 if (element == *input_element) { | 179 if (element == *input_element) { |
165 int length = input_element->value().length(); | 180 int length = input_element->value().length(); |
166 input_element->setSelectionRange(length, length); | 181 input_element->setSelectionRange(length, length); |
167 } | 182 } |
168 } else { | 183 } else if (IsSelectElement(control_element)) { |
169 DCHECK(IsSelectElement(control_element)); | |
170 WebSelectElement select_element = control_element.to<WebSelectElement>(); | 184 WebSelectElement select_element = control_element.to<WebSelectElement>(); |
171 | 185 |
172 std::map<const WebSelectElement, string16>::const_iterator | 186 std::map<const WebSelectElement, string16>::const_iterator |
173 initial_value_iter = initial_select_values_.find(select_element); | 187 initial_value_iter = initial_select_values_.find(select_element); |
174 if (initial_value_iter != initial_select_values_.end() && | 188 if (initial_value_iter != initial_select_values_.end() && |
175 select_element.value() != initial_value_iter->second) { | 189 select_element.value() != initial_value_iter->second) { |
176 select_element.setValue(initial_value_iter->second); | 190 select_element.setValue(initial_value_iter->second); |
177 select_element.dispatchFormControlChangeEvent(); | 191 select_element.dispatchFormControlChangeEvent(); |
178 } | 192 } |
193 } else { | |
194 WebInputElement input_element = control_element.to<WebInputElement>(); | |
195 DCHECK(IsRadioButtonElement(&input_element) || | |
196 IsCheckboxElement(&input_element)); | |
197 std::map<const WebInputElement, bool>::const_iterator it = | |
198 initial_checked_state_.find(input_element); | |
199 if (it != initial_checked_state_.end() && | |
200 input_element.isChecked() != it->second) { | |
201 input_element.setChecked(it->second, true); | |
202 } | |
179 } | 203 } |
180 } | 204 } |
181 | 205 |
182 return true; | 206 return true; |
183 } | 207 } |
184 | 208 |
185 bool FormCache::ShowPredictions(const FormDataPredictions& form) { | 209 bool FormCache::ShowPredictions(const FormDataPredictions& form) { |
186 DCHECK_EQ(form.data.fields.size(), form.fields.size()); | 210 DCHECK_EQ(form.data.fields.size(), form.fields.size()); |
187 | 211 |
188 // Find the form. | 212 // Find the form. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 UTF8ToUTF16(form.experiment_id)); | 268 UTF8ToUTF16(form.experiment_id)); |
245 if (!element->hasAttribute("placeholder")) | 269 if (!element->hasAttribute("placeholder")) |
246 element->setAttribute("placeholder", WebString(UTF8ToUTF16(placeholder))); | 270 element->setAttribute("placeholder", WebString(UTF8ToUTF16(placeholder))); |
247 element->setAttribute("title", WebString(title)); | 271 element->setAttribute("title", WebString(title)); |
248 } | 272 } |
249 | 273 |
250 return true; | 274 return true; |
251 } | 275 } |
252 | 276 |
253 } // namespace autofill | 277 } // namespace autofill |
OLD | NEW |