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/autofill_agent.h" | 5 #include "chrome/renderer/autofill/autofill_agent.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "chrome/common/autofill_messages.h" | 11 #include "chrome/common/autofill_messages.h" |
12 #include "chrome/common/chrome_constants.h" | 12 #include "chrome/common/chrome_constants.h" |
13 #include "chrome/renderer/autofill/form_autofill_util.h" | 13 #include "chrome/renderer/autofill/form_autofill_util.h" |
14 #include "chrome/renderer/autofill/password_autofill_manager.h" | 14 #include "chrome/renderer/autofill/password_autofill_manager.h" |
15 #include "content/public/renderer/render_view.h" | 15 #include "content/public/renderer/render_view.h" |
16 #include "grit/chromium_strings.h" | 16 #include "grit/chromium_strings.h" |
17 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataListElement.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h" |
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeCollection.h" | |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebOptionElement.h" | |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | |
25 #include "ui/base/keycodes/keyboard_codes.h" | 28 #include "ui/base/keycodes/keyboard_codes.h" |
26 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
27 #include "webkit/forms/form_data.h" | 30 #include "webkit/forms/form_data.h" |
28 #include "webkit/forms/form_data_predictions.h" | 31 #include "webkit/forms/form_data_predictions.h" |
29 #include "webkit/forms/form_field.h" | 32 #include "webkit/forms/form_field.h" |
30 #include "webkit/forms/password_form.h" | 33 #include "webkit/forms/password_form.h" |
31 | 34 |
35 using WebKit::WebDataListElement; | |
32 using WebKit::WebFormControlElement; | 36 using WebKit::WebFormControlElement; |
33 using WebKit::WebFormElement; | 37 using WebKit::WebFormElement; |
34 using WebKit::WebFrame; | 38 using WebKit::WebFrame; |
35 using WebKit::WebInputElement; | 39 using WebKit::WebInputElement; |
36 using WebKit::WebKeyboardEvent; | 40 using WebKit::WebKeyboardEvent; |
37 using WebKit::WebNode; | 41 using WebKit::WebNode; |
42 using WebKit::WebNodeCollection; | |
43 using WebKit::WebOptionElement; | |
38 using WebKit::WebString; | 44 using WebKit::WebString; |
39 using webkit::forms::FormData; | 45 using webkit::forms::FormData; |
40 using webkit::forms::FormDataPredictions; | 46 using webkit::forms::FormDataPredictions; |
41 | 47 |
42 namespace { | 48 namespace { |
43 | 49 |
44 // The size above which we stop triggering autofill for an input text field | 50 // The size above which we stop triggering autofill for an input text field |
45 // (so to avoid sending long strings through IPC). | 51 // (so to avoid sending long strings through IPC). |
46 const size_t kMaximumTextSizeForAutofill = 1000; | 52 const size_t kMaximumTextSizeForAutofill = 1000; |
47 | 53 |
48 } // namespace | 54 } // namespace |
49 | 55 |
50 namespace autofill { | 56 namespace autofill { |
51 | 57 |
52 AutofillAgent::AutofillAgent( | 58 AutofillAgent::AutofillAgent( |
53 content::RenderView* render_view, | 59 content::RenderView* render_view, |
54 PasswordAutofillManager* password_autofill_manager) | 60 PasswordAutofillManager* password_autofill_manager) |
55 : content::RenderViewObserver(render_view), | 61 : content::RenderViewObserver(render_view), |
56 password_autofill_manager_(password_autofill_manager), | 62 password_autofill_manager_(password_autofill_manager), |
57 autofill_query_id_(0), | 63 autofill_query_id_(0), |
58 autofill_action_(AUTOFILL_NONE), | 64 autofill_action_(AUTOFILL_NONE), |
59 display_warning_if_disabled_(false), | 65 display_warning_if_disabled_(false), |
60 was_query_node_autofilled_(false), | 66 was_query_node_autofilled_(false), |
61 suggestions_clear_index_(-1), | |
62 suggestions_options_index_(-1), | |
63 has_shown_autofill_popup_for_current_edit_(false), | 67 has_shown_autofill_popup_for_current_edit_(false), |
64 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 68 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
65 render_view->GetWebView()->setAutofillClient(this); | 69 render_view->GetWebView()->setAutofillClient(this); |
66 } | 70 } |
67 | 71 |
68 AutofillAgent::~AutofillAgent() {} | 72 AutofillAgent::~AutofillAgent() {} |
69 | 73 |
70 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { | 74 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { |
71 bool handled = true; | 75 bool handled = true; |
72 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) | 76 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 | 143 |
140 bool AutofillAgent::InputElementLostFocus() { | 144 bool AutofillAgent::InputElementLostFocus() { |
141 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); | 145 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); |
142 | 146 |
143 return false; | 147 return false; |
144 } | 148 } |
145 | 149 |
146 void AutofillAgent::didAcceptAutofillSuggestion(const WebNode& node, | 150 void AutofillAgent::didAcceptAutofillSuggestion(const WebNode& node, |
147 const WebString& value, | 151 const WebString& value, |
148 const WebString& label, | 152 const WebString& label, |
149 int unique_id, | 153 int item_id, |
150 unsigned index) { | 154 unsigned index) { |
151 if (password_autofill_manager_->DidAcceptAutofillSuggestion(node, value)) | 155 if (password_autofill_manager_->DidAcceptAutofillSuggestion(node, value)) |
152 return; | 156 return; |
153 | 157 |
154 DCHECK(node == autofill_query_element_); | 158 DCHECK(node == autofill_query_element_); |
155 | 159 |
156 if (suggestions_options_index_ != -1 && | 160 switch (item_id) { |
157 index == static_cast<unsigned>(suggestions_options_index_)) { | 161 case WebKit::WarningMessageMenuItemID: |
Ilya Sherman
2012/04/11 00:18:04
If we are going to be relying on all warnings bein
keishi
2012/04/11 11:48:08
Done.
| |
158 // User selected 'Autofill Options'. | 162 case WebKit::SeparatorMenuItemID: { |
Ilya Sherman
2012/04/11 00:18:04
nit: Please preserve these comments. I admit that
keishi
2012/04/11 11:48:08
Done.
| |
159 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id())); | 163 NOTREACHED(); |
160 } else if (suggestions_clear_index_ != -1 && | 164 break; |
161 index == static_cast<unsigned>(suggestions_clear_index_)) { | 165 } |
Ilya Sherman
2012/04/11 00:18:04
nit: No need for curly braces.
keishi
2012/04/11 11:48:08
Done.
| |
162 // User selected 'Clear form'. | 166 case WebKit::AutofillOptionsMenuItemID: { |
163 form_cache_.ClearFormWithElement(autofill_query_element_); | 167 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id())); |
164 } else if (!unique_id) { | 168 break; |
165 // User selected an Autocomplete entry, so we fill directly. | 169 } |
166 WebInputElement element = node.toConst<WebInputElement>(); | 170 case WebKit::ClearFormMenuItemID: { |
167 SetNodeText(value, &element); | 171 form_cache_.ClearFormWithElement(autofill_query_element_); |
168 } else { | 172 break; |
169 // Fill the values for the whole form. | 173 } |
170 FillAutofillFormData(node, unique_id, AUTOFILL_FILL); | 174 case WebKit::AutocompleteEntryMenuItemID: |
175 case WebKit::PasswordEntryMenuItemID: | |
176 case WebKit::DataListEntryMenuItemID: { | |
177 WebInputElement element = node.toConst<WebInputElement>(); | |
Ilya Sherman
2012/04/11 00:18:04
nit: Perhaps we can skip this cast by using |autof
keishi
2012/04/11 11:48:08
Done.
| |
178 SetNodeText(value, &element); | |
179 break; | |
180 } | |
181 default: { | |
182 // Fill the values for the whole form. | |
Ilya Sherman
2012/04/11 00:18:04
nit: It's probably a good idea to DCHECK_GT(item_i
keishi
2012/04/11 11:48:08
Done.
| |
183 FillAutofillFormData(node, item_id, AUTOFILL_FILL); | |
184 } | |
171 } | 185 } |
172 | |
173 suggestions_clear_index_ = -1; | |
174 suggestions_options_index_ = -1; | |
175 } | 186 } |
176 | 187 |
177 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node, | 188 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node, |
178 const WebString& value, | 189 const WebString& value, |
179 const WebString& label, | 190 const WebString& label, |
180 int unique_id) { | 191 int item_id) { |
181 DCHECK_GE(unique_id, 0); | 192 DCHECK_GE(item_id, 0); |
Ilya Sherman
2012/04/11 00:18:04
Is this still valid? Which sorts of items are sel
keishi
2012/04/11 11:48:08
No, it was wrong. Selecting a non autofill entry s
| |
182 if (password_autofill_manager_->DidSelectAutofillSuggestion(node)) | 193 if (password_autofill_manager_->DidSelectAutofillSuggestion(node)) |
183 return; | 194 return; |
184 | 195 |
185 didClearAutofillSelection(node); | 196 didClearAutofillSelection(node); |
186 FillAutofillFormData(node, unique_id, AUTOFILL_PREVIEW); | 197 FillAutofillFormData(node, item_id, AUTOFILL_PREVIEW); |
187 } | 198 } |
188 | 199 |
189 void AutofillAgent::didClearAutofillSelection(const WebNode& node) { | 200 void AutofillAgent::didClearAutofillSelection(const WebNode& node) { |
190 if (password_autofill_manager_->DidClearAutofillSelection(node)) | 201 if (password_autofill_manager_->DidClearAutofillSelection(node)) |
191 return; | 202 return; |
192 | 203 |
193 if (!autofill_query_element_.isNull() && node == autofill_query_element_) { | 204 if (!autofill_query_element_.isNull() && node == autofill_query_element_) { |
194 ClearPreviewedFormWithElement(autofill_query_element_, | 205 ClearPreviewedFormWithElement(autofill_query_element_, |
195 was_query_node_autofilled_); | 206 was_query_node_autofilled_); |
196 } else { | 207 } else { |
197 // TODO(isherman): There seem to be rare cases where this code *is* | 208 // TODO(isherman): There seem to be rare cases where this code *is* |
198 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would | 209 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would |
199 // understand those cases and fix the code to avoid them. However, so far I | 210 // understand those cases and fix the code to avoid them. However, so far I |
200 // have been unable to reproduce such a case locally. If you hit this | 211 // have been unable to reproduce such a case locally. If you hit this |
201 // NOTREACHED(), please file a bug against me. | 212 // NOTREACHED(), please file a bug against me. |
202 NOTREACHED(); | 213 NOTREACHED(); |
203 } | 214 } |
204 } | 215 } |
205 | 216 |
206 void AutofillAgent::removeAutocompleteSuggestion(const WebString& name, | 217 void AutofillAgent::removeAutocompleteSuggestion(const WebString& name, |
207 const WebString& value) { | 218 const WebString& value) { |
208 // The index of clear & options will have shifted down. | |
209 if (suggestions_clear_index_ != -1) | |
210 suggestions_clear_index_--; | |
211 if (suggestions_options_index_ != -1) | |
212 suggestions_options_index_--; | |
213 | |
214 Send(new AutofillHostMsg_RemoveAutocompleteEntry(routing_id(), name, value)); | 219 Send(new AutofillHostMsg_RemoveAutocompleteEntry(routing_id(), name, value)); |
215 } | 220 } |
216 | 221 |
217 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { | 222 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { |
218 password_autofill_manager_->TextFieldDidEndEditing(element); | 223 password_autofill_manager_->TextFieldDidEndEditing(element); |
219 has_shown_autofill_popup_for_current_edit_ = false; | 224 has_shown_autofill_popup_for_current_edit_ = false; |
220 Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id())); | 225 Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id())); |
221 } | 226 } |
222 | 227 |
223 void AutofillAgent::textFieldDidChange(const WebInputElement& element) { | 228 void AutofillAgent::textFieldDidChange(const WebInputElement& element) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 if (values.empty()) { | 276 if (values.empty()) { |
272 // No suggestions, any popup currently showing is obsolete. | 277 // No suggestions, any popup currently showing is obsolete. |
273 web_view->hidePopups(); | 278 web_view->hidePopups(); |
274 return; | 279 return; |
275 } | 280 } |
276 | 281 |
277 std::vector<string16> v(values); | 282 std::vector<string16> v(values); |
278 std::vector<string16> l(labels); | 283 std::vector<string16> l(labels); |
279 std::vector<string16> i(icons); | 284 std::vector<string16> i(icons); |
280 std::vector<int> ids(unique_ids); | 285 std::vector<int> ids(unique_ids); |
281 int separator_index = -1; | |
282 | 286 |
283 DCHECK_GT(ids.size(), 0U); | 287 DCHECK_GT(ids.size(), 0U); |
284 if (!autofill_query_element_.isNull() && | 288 if (!autofill_query_element_.isNull() && |
285 !autofill_query_element_.autoComplete()) { | 289 !autofill_query_element_.autoComplete()) { |
286 // If autofill is disabled and we had suggestions, show a warning instead. | 290 // If autofill is disabled and we had suggestions, show a warning instead. |
287 v.assign(1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); | 291 v.assign(1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); |
288 l.assign(1, string16()); | 292 l.assign(1, string16()); |
289 i.assign(1, string16()); | 293 i.assign(1, string16()); |
290 ids.assign(1, -1); | 294 ids.assign(1, WebKit::WarningMessageMenuItemID); |
291 } else if (ids[0] < 0 && ids.size() > 1) { | 295 } else if (ids[0] < 0 && ids.size() > 1) { |
292 // If we received a warning instead of suggestions from autofill but regular | 296 // If we received a warning instead of suggestions from autofill but regular |
293 // suggestions from autocomplete, don't show the autofill warning. | 297 // suggestions from autocomplete, don't show the autofill warning. |
294 v.erase(v.begin()); | 298 v.erase(v.begin()); |
295 l.erase(l.begin()); | 299 l.erase(l.begin()); |
296 i.erase(i.begin()); | 300 i.erase(i.begin()); |
297 ids.erase(ids.begin()); | 301 ids.erase(ids.begin()); |
298 } | 302 } |
299 | 303 |
300 // If we were about to show a warning and we shouldn't, don't. | 304 // If we were about to show a warning and we shouldn't, don't. |
(...skipping 10 matching lines...) Expand all Loading... | |
311 } | 315 } |
312 } | 316 } |
313 | 317 |
314 // The form has been auto-filled, so give the user the chance to clear the | 318 // The form has been auto-filled, so give the user the chance to clear the |
315 // form. Append the 'Clear form' menu item. | 319 // form. Append the 'Clear form' menu item. |
316 if (has_autofill_item && | 320 if (has_autofill_item && |
317 FormWithElementIsAutofilled(autofill_query_element_)) { | 321 FormWithElementIsAutofilled(autofill_query_element_)) { |
318 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM)); | 322 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM)); |
319 l.push_back(string16()); | 323 l.push_back(string16()); |
320 i.push_back(string16()); | 324 i.push_back(string16()); |
321 ids.push_back(0); | 325 ids.push_back(WebKit::ClearFormMenuItemID); |
322 suggestions_clear_index_ = v.size() - 1; | 326 |
323 separator_index = v.size() - 1; | 327 v.push_back(string16()); |
328 l.push_back(string16()); | |
329 i.push_back(string16()); | |
330 ids.push_back(WebKit::SeparatorMenuItemID); | |
Ilya Sherman
2012/04/11 00:18:04
This was not actually showing up as a separator in
keishi
2012/04/11 11:48:08
The separator should come before the menu item. Fi
| |
324 } | 331 } |
325 | 332 |
326 if (has_autofill_item) { | 333 if (has_autofill_item) { |
327 // Append the 'Chrome Autofill options' menu item; | 334 // Append the 'Chrome Autofill options' menu item; |
328 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP)); | 335 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP)); |
329 l.push_back(string16()); | 336 l.push_back(string16()); |
330 i.push_back(string16()); | 337 i.push_back(string16()); |
331 ids.push_back(0); | 338 ids.push_back(WebKit::AutofillOptionsMenuItemID); |
332 suggestions_options_index_ = v.size() - 1; | 339 |
333 separator_index = values.size(); | 340 v.push_back(string16()); |
341 l.push_back(string16()); | |
342 i.push_back(string16()); | |
343 ids.push_back(WebKit::SeparatorMenuItemID); | |
Ilya Sherman
2012/04/11 00:18:04
This can add two separators where we should have o
keishi
2012/04/11 11:48:08
Done.
| |
334 } | 344 } |
335 | 345 |
336 // Send to WebKit for display. | 346 // Send to WebKit for display. |
337 if (!v.empty() && !autofill_query_element_.isNull() && | 347 if (!v.empty() && !autofill_query_element_.isNull() && |
338 autofill_query_element_.isFocusable()) { | 348 autofill_query_element_.isFocusable()) { |
339 web_view->applyAutofillSuggestions( | 349 CombineDataListEntriesAndShow(autofill_query_element_, v, l, i, ids); |
340 autofill_query_element_, v, l, i, ids, separator_index); | |
341 } | 350 } |
342 | 351 |
343 Send(new AutofillHostMsg_DidShowAutofillSuggestions( | 352 Send(new AutofillHostMsg_DidShowAutofillSuggestions( |
344 routing_id(), | 353 routing_id(), |
345 has_autofill_item && !has_shown_autofill_popup_for_current_edit_)); | 354 has_autofill_item && !has_shown_autofill_popup_for_current_edit_)); |
346 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item; | 355 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item; |
347 } | 356 } |
348 | 357 |
358 void AutofillAgent::CombineDataListEntriesAndShow(const WebKit::WebInputElement& element, | |
359 const std::vector<string16>& values, | |
360 const std::vector<string16>& labels, | |
361 const std::vector<string16>& icons, | |
362 const std::vector<int>& item_ids) { | |
Ilya Sherman
2012/04/11 00:18:04
nit: 80-col, wrapping
keishi
2012/04/11 11:48:08
Done.
| |
363 std::vector<string16> v; | |
364 std::vector<string16> l; | |
365 std::vector<string16> i; | |
366 std::vector<int> ids; | |
367 | |
368 WebDataListElement dataList = element.dataList(); | |
369 if (!dataList.isNull()) { | |
370 WebNodeCollection options = dataList.options(); | |
371 if (options.length() > 0) { | |
Ilya Sherman
2012/04/11 00:18:04
nit: Is this check needed, or would it also be cov
keishi
2012/04/11 11:48:08
True! Removed.
| |
372 WebOptionElement option = options.firstItem().to<WebOptionElement>(); | |
373 while (!option.isNull()) { | |
374 v.push_back(option.value()); | |
375 if (option.value() != option.label()) | |
376 l.push_back(option.label()); | |
377 else | |
378 l.push_back(string16()); | |
379 i.push_back(string16()); | |
380 ids.push_back(WebKit::DataListEntryMenuItemID); | |
381 option = options.nextItem().to<WebOptionElement>(); | |
382 } | |
383 } | |
384 } | |
Ilya Sherman
2012/04/11 00:18:04
nit: This code has a lot of levels of nesting. Th
keishi
2012/04/11 11:48:08
Done.
| |
385 | |
386 if (v.size() > 0 && values.size() > 0) { | |
Ilya Sherman
2012/04/11 00:18:04
nit: Please add a comment above this if-stmt -- so
keishi
2012/04/11 11:48:08
Done.
| |
387 v.push_back(string16()); | |
388 l.push_back(string16()); | |
389 i.push_back(string16()); | |
390 ids.push_back(WebKit::SeparatorMenuItemID); | |
391 } | |
392 | |
393 v.insert(v.end(), values.begin(), values.end()); | |
394 l.insert(l.end(), labels.begin(), labels.end()); | |
395 i.insert(i.end(), icons.begin(), icons.end()); | |
396 ids.insert(ids.end(), item_ids.begin(), item_ids.end()); | |
397 | |
398 render_view()->GetWebView()->applyAutofillSuggestions(element, v, l, i, ids); | |
399 } | |
400 | |
349 void AutofillAgent::OnFormDataFilled(int query_id, | 401 void AutofillAgent::OnFormDataFilled(int query_id, |
350 const webkit::forms::FormData& form) { | 402 const webkit::forms::FormData& form) { |
351 if (!render_view()->GetWebView() || query_id != autofill_query_id_) | 403 if (!render_view()->GetWebView() || query_id != autofill_query_id_) |
352 return; | 404 return; |
353 | 405 |
354 was_query_node_autofilled_ = autofill_query_element_.isAutofilled(); | 406 was_query_node_autofilled_ = autofill_query_element_.isAutofilled(); |
355 | 407 |
356 switch (autofill_action_) { | 408 switch (autofill_action_) { |
357 case AUTOFILL_FILL: | 409 case AUTOFILL_FILL: |
358 FillForm(form, autofill_query_element_); | 410 FillForm(form, autofill_query_element_); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion( | 463 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion( |
412 autofill_query_element_, | 464 autofill_query_element_, |
413 value); | 465 value); |
414 DCHECK(handled); | 466 DCHECK(handled); |
415 } | 467 } |
416 | 468 |
417 void AutofillAgent::ShowSuggestions(const WebInputElement& element, | 469 void AutofillAgent::ShowSuggestions(const WebInputElement& element, |
418 bool autofill_on_empty_values, | 470 bool autofill_on_empty_values, |
419 bool requires_caret_at_end, | 471 bool requires_caret_at_end, |
420 bool display_warning_if_disabled) { | 472 bool display_warning_if_disabled) { |
421 // If autocomplete is disabled at the form level, then we might want to show | 473 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || element.isPasswordField() || !element.suggestedValue().isEmpty()) |
Ilya Sherman
2012/04/11 00:18:04
nit: 80-col
keishi
2012/04/11 11:48:08
Done.
| |
422 // a warning in place of suggestions. However, if autocomplete is disabled | |
423 // specifically for this field, we never want to show a warning. Otherwise, | |
424 // we might interfere with custom popups (e.g. search suggestions) used by | |
425 // the website. | |
426 const WebFormElement form = element.form(); | |
427 if (!element.isEnabled() || element.isReadOnly() || | |
428 (!element.autoComplete() && (form.isNull() || form.autoComplete())) || | |
429 !element.isTextField() || element.isPasswordField() || | |
430 !element.suggestedValue().isEmpty()) | |
431 return; | |
432 | |
433 // If the field has no name, then we won't have values. | |
434 if (element.nameForAutofill().isEmpty()) | |
435 return; | 474 return; |
436 | 475 |
437 // Don't attempt to autofill with values that are too large or if filling | 476 // Don't attempt to autofill with values that are too large or if filling |
438 // criteria are not met. | 477 // criteria are not met. |
439 WebString value = element.value(); | 478 WebString value = element.value(); |
440 if (value.length() > kMaximumTextSizeForAutofill || | 479 if (value.length() > kMaximumTextSizeForAutofill || |
441 (!autofill_on_empty_values && value.isEmpty()) || | 480 (!autofill_on_empty_values && value.isEmpty()) || |
442 (requires_caret_at_end && | 481 (requires_caret_at_end && |
443 (element.selectionStart() != element.selectionEnd() || | 482 (element.selectionStart() != element.selectionEnd() || |
444 element.selectionEnd() != static_cast<int>(value.length())))) { | 483 element.selectionEnd() != static_cast<int>(value.length())))) { |
445 // Any popup currently showing is obsolete. | 484 // Any popup currently showing is obsolete. |
446 WebKit::WebView* web_view = render_view()->GetWebView(); | 485 WebKit::WebView* web_view = render_view()->GetWebView(); |
447 if (web_view) | 486 if (web_view) |
448 web_view->hidePopups(); | 487 web_view->hidePopups(); |
449 | 488 |
450 return; | 489 return; |
451 } | 490 } |
491 | |
492 // If autocomplete is disabled at the form level, then we might want to show | |
493 // a warning in place of suggestions. However, if autocomplete is disabled | |
494 // specifically for this field, we never want to show a warning. Otherwise, | |
495 // we might interfere with custom popups (e.g. search suggestions) used by | |
496 // the website. | |
497 const WebFormElement form = element.form(); | |
498 if ((!element.autoComplete() && (form.isNull() || form.autoComplete())) || | |
499 // If the field has no name, then we won't have values. | |
Ilya Sherman
2012/04/11 00:18:04
nit: Please move this comment to be above the if-s
keishi
2012/04/11 11:48:08
Done.
| |
500 element.nameForAutofill().isEmpty()) { | |
501 CombineDataListEntriesAndShow(element, std::vector<string16>(), std::vector< string16>(), std::vector<string16>(), std::vector<int>()); | |
Ilya Sherman
2012/04/11 00:18:04
nit: 80-col.
keishi
2012/04/11 11:48:08
Done.
| |
502 return; | |
503 } | |
452 | 504 |
453 QueryAutofillSuggestions(element, display_warning_if_disabled); | 505 QueryAutofillSuggestions(element, display_warning_if_disabled); |
454 } | 506 } |
455 | 507 |
456 void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element, | 508 void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element, |
457 bool display_warning_if_disabled) { | 509 bool display_warning_if_disabled) { |
458 static int query_counter = 0; | 510 static int query_counter = 0; |
459 autofill_query_id_ = query_counter++; | 511 autofill_query_id_ = query_counter++; |
460 autofill_query_element_ = element; | 512 autofill_query_element_ = element; |
461 display_warning_if_disabled_ = display_warning_if_disabled; | 513 display_warning_if_disabled_ = display_warning_if_disabled; |
(...skipping 11 matching lines...) Expand all Loading... | |
473 | 525 |
474 Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(), | 526 Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(), |
475 autofill_query_id_, | 527 autofill_query_id_, |
476 form, | 528 form, |
477 field, | 529 field, |
478 bounding_box, | 530 bounding_box, |
479 display_warning_if_disabled)); | 531 display_warning_if_disabled)); |
480 } | 532 } |
481 | 533 |
482 void AutofillAgent::FillAutofillFormData(const WebNode& node, | 534 void AutofillAgent::FillAutofillFormData(const WebNode& node, |
483 int unique_id, | 535 int item_id, |
484 AutofillAction action) { | 536 AutofillAction action) { |
485 static int query_counter = 0; | 537 static int query_counter = 0; |
486 autofill_query_id_ = query_counter++; | 538 autofill_query_id_ = query_counter++; |
487 | 539 |
488 webkit::forms::FormData form; | 540 webkit::forms::FormData form; |
489 webkit::forms::FormField field; | 541 webkit::forms::FormField field; |
490 if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form, | 542 if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form, |
491 &field, REQUIRE_AUTOCOMPLETE)) { | 543 &field, REQUIRE_AUTOCOMPLETE)) { |
492 return; | 544 return; |
493 } | 545 } |
494 | 546 |
495 autofill_action_ = action; | 547 autofill_action_ = action; |
496 Send(new AutofillHostMsg_FillAutofillFormData( | 548 Send(new AutofillHostMsg_FillAutofillFormData( |
497 routing_id(), autofill_query_id_, form, field, unique_id)); | 549 routing_id(), autofill_query_id_, form, field, item_id)); |
498 } | 550 } |
499 | 551 |
500 void AutofillAgent::SetNodeText(const string16& value, | 552 void AutofillAgent::SetNodeText(const string16& value, |
501 WebKit::WebInputElement* node) { | 553 WebKit::WebInputElement* node) { |
502 string16 substring = value; | 554 string16 substring = value; |
503 substring = substring.substr(0, node->maxLength()); | 555 substring = substring.substr(0, node->maxLength()); |
504 | 556 |
505 node->setValue(substring, true); | 557 node->setValue(substring, true); |
506 } | 558 } |
507 | 559 |
508 } // namespace autofill | 560 } // namespace autofill |
OLD | NEW |