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" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { | 70 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { |
71 bool handled = true; | 71 bool handled = true; |
72 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) | 72 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) |
73 IPC_MESSAGE_HANDLER(AutofillMsg_SuggestionsReturned, OnSuggestionsReturned) | 73 IPC_MESSAGE_HANDLER(AutofillMsg_SuggestionsReturned, OnSuggestionsReturned) |
74 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled) | 74 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled) |
75 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable, | 75 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable, |
76 OnFieldTypePredictionsAvailable) | 76 OnFieldTypePredictionsAvailable) |
77 IPC_MESSAGE_HANDLER(AutofillMsg_SelectAutofillSuggestionAtIndex, | 77 IPC_MESSAGE_HANDLER(AutofillMsg_SelectAutofillSuggestionAtIndex, |
78 OnSelectAutofillSuggestionAtIndex) | 78 OnSelectAutofillSuggestionAtIndex) |
| 79 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill, |
| 80 OnSetAutofillActionFill) |
| 81 IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm, |
| 82 OnClearForm) |
| 83 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview, |
| 84 OnSetAutofillActionPreview) |
| 85 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm, |
| 86 OnClearPreviewedForm) |
| 87 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText, |
| 88 OnSetNodeText) |
79 IPC_MESSAGE_UNHANDLED(handled = false) | 89 IPC_MESSAGE_UNHANDLED(handled = false) |
80 IPC_END_MESSAGE_MAP() | 90 IPC_END_MESSAGE_MAP() |
81 return handled; | 91 return handled; |
82 } | 92 } |
83 | 93 |
84 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { | 94 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { |
85 // The document has now been fully loaded. Scan for forms to be sent up to | 95 // The document has now been fully loaded. Scan for forms to be sent up to |
86 // the browser. | 96 // the browser. |
87 std::vector<webkit::forms::FormData> forms; | 97 std::vector<webkit::forms::FormData> forms; |
88 form_cache_.ExtractForms(*frame, &forms); | 98 form_cache_.ExtractForms(*frame, &forms); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 } | 142 } |
133 | 143 |
134 void AutofillAgent::didAcceptAutofillSuggestion(const WebNode& node, | 144 void AutofillAgent::didAcceptAutofillSuggestion(const WebNode& node, |
135 const WebString& value, | 145 const WebString& value, |
136 const WebString& label, | 146 const WebString& label, |
137 int unique_id, | 147 int unique_id, |
138 unsigned index) { | 148 unsigned index) { |
139 if (password_autofill_manager_->DidAcceptAutofillSuggestion(node, value)) | 149 if (password_autofill_manager_->DidAcceptAutofillSuggestion(node, value)) |
140 return; | 150 return; |
141 | 151 |
| 152 DCHECK(node == autofill_query_element_); |
| 153 |
142 if (suggestions_options_index_ != -1 && | 154 if (suggestions_options_index_ != -1 && |
143 index == static_cast<unsigned>(suggestions_options_index_)) { | 155 index == static_cast<unsigned>(suggestions_options_index_)) { |
144 // User selected 'Autofill Options'. | 156 // User selected 'Autofill Options'. |
145 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id())); | 157 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id())); |
146 } else if (suggestions_clear_index_ != -1 && | 158 } else if (suggestions_clear_index_ != -1 && |
147 index == static_cast<unsigned>(suggestions_clear_index_)) { | 159 index == static_cast<unsigned>(suggestions_clear_index_)) { |
148 // User selected 'Clear form'. | 160 // User selected 'Clear form'. |
149 DCHECK(node == autofill_query_element_); | |
150 form_cache_.ClearFormWithElement(autofill_query_element_); | 161 form_cache_.ClearFormWithElement(autofill_query_element_); |
151 } else if (!unique_id) { | 162 } else if (!unique_id) { |
152 // User selected an Autocomplete entry, so we fill directly. | 163 // User selected an Autocomplete entry, so we fill directly. |
153 WebInputElement element = node.toConst<WebInputElement>(); | 164 WebInputElement element = node.toConst<WebInputElement>(); |
154 | 165 SetNodeText(value, &element); |
155 string16 substring = value; | |
156 substring = substring.substr(0, element.maxLength()); | |
157 element.setValue(substring, true); | |
158 } else { | 166 } else { |
159 // Fill the values for the whole form. | 167 // Fill the values for the whole form. |
160 FillAutofillFormData(node, unique_id, AUTOFILL_FILL); | 168 FillAutofillFormData(node, unique_id, AUTOFILL_FILL); |
161 } | 169 } |
162 | 170 |
163 suggestions_clear_index_ = -1; | 171 suggestions_clear_index_ = -1; |
164 suggestions_options_index_ = -1; | 172 suggestions_options_index_ = -1; |
165 } | 173 } |
166 | 174 |
167 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node, | 175 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 routing_id(), | 338 routing_id(), |
331 has_autofill_item && !has_shown_autofill_popup_for_current_edit_)); | 339 has_autofill_item && !has_shown_autofill_popup_for_current_edit_)); |
332 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item; | 340 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item; |
333 } | 341 } |
334 | 342 |
335 void AutofillAgent::OnFormDataFilled(int query_id, | 343 void AutofillAgent::OnFormDataFilled(int query_id, |
336 const webkit::forms::FormData& form) { | 344 const webkit::forms::FormData& form) { |
337 if (!render_view()->GetWebView() || query_id != autofill_query_id_) | 345 if (!render_view()->GetWebView() || query_id != autofill_query_id_) |
338 return; | 346 return; |
339 | 347 |
| 348 was_query_node_autofilled_ = autofill_query_element_.isAutofilled(); |
| 349 |
340 switch (autofill_action_) { | 350 switch (autofill_action_) { |
341 case AUTOFILL_FILL: | 351 case AUTOFILL_FILL: |
342 FillForm(form, autofill_query_element_); | 352 FillForm(form, autofill_query_element_); |
343 Send(new AutofillHostMsg_DidFillAutofillFormData(routing_id(), | 353 Send(new AutofillHostMsg_DidFillAutofillFormData(routing_id(), |
344 base::TimeTicks::Now())); | 354 base::TimeTicks::Now())); |
345 break; | 355 break; |
346 case AUTOFILL_PREVIEW: | 356 case AUTOFILL_PREVIEW: |
| 357 didClearAutofillSelection(autofill_query_element_); |
| 358 |
347 PreviewForm(form, autofill_query_element_); | 359 PreviewForm(form, autofill_query_element_); |
348 Send(new AutofillHostMsg_DidPreviewAutofillFormData(routing_id())); | 360 Send(new AutofillHostMsg_DidPreviewAutofillFormData(routing_id())); |
349 break; | 361 break; |
350 default: | 362 default: |
351 NOTREACHED(); | 363 NOTREACHED(); |
352 } | 364 } |
353 autofill_action_ = AUTOFILL_NONE; | 365 autofill_action_ = AUTOFILL_NONE; |
354 } | 366 } |
355 | 367 |
356 void AutofillAgent::OnFieldTypePredictionsAvailable( | 368 void AutofillAgent::OnFieldTypePredictionsAvailable( |
357 const std::vector<FormDataPredictions>& forms) { | 369 const std::vector<FormDataPredictions>& forms) { |
358 for (size_t i = 0; i < forms.size(); ++i) { | 370 for (size_t i = 0; i < forms.size(); ++i) { |
359 form_cache_.ShowPredictions(forms[i]); | 371 form_cache_.ShowPredictions(forms[i]); |
360 } | 372 } |
361 } | 373 } |
362 | 374 |
363 void AutofillAgent::OnSelectAutofillSuggestionAtIndex(int listIndex) { | 375 void AutofillAgent::OnSelectAutofillSuggestionAtIndex(int listIndex) { |
364 NOTIMPLEMENTED(); | 376 NOTIMPLEMENTED(); |
365 // TODO(jrg): enable once changes land in WebKit | 377 // TODO(jrg): enable once changes land in WebKit |
366 // render_view()->webview()->selectAutofillSuggestionAtIndex(listIndex); | 378 // render_view()->webview()->selectAutofillSuggestionAtIndex(listIndex); |
367 } | 379 } |
368 | 380 |
| 381 void AutofillAgent::OnSetAutofillActionFill() { |
| 382 autofill_action_ = AUTOFILL_FILL; |
| 383 } |
| 384 |
| 385 void AutofillAgent::OnClearForm() { |
| 386 form_cache_.ClearFormWithElement(autofill_query_element_); |
| 387 } |
| 388 |
| 389 void AutofillAgent::OnSetAutofillActionPreview() { |
| 390 autofill_action_ = AUTOFILL_PREVIEW; |
| 391 } |
| 392 |
| 393 void AutofillAgent::OnClearPreviewedForm() { |
| 394 didClearAutofillSelection(autofill_query_element_); |
| 395 } |
| 396 |
| 397 void AutofillAgent::OnSetNodeText(const string16& value) { |
| 398 SetNodeText(value, &autofill_query_element_); |
| 399 } |
| 400 |
369 void AutofillAgent::ShowSuggestions(const WebInputElement& element, | 401 void AutofillAgent::ShowSuggestions(const WebInputElement& element, |
370 bool autofill_on_empty_values, | 402 bool autofill_on_empty_values, |
371 bool requires_caret_at_end, | 403 bool requires_caret_at_end, |
372 bool display_warning_if_disabled) { | 404 bool display_warning_if_disabled) { |
373 // If autocomplete is disabled at the form level, then we might want to show | 405 // If autocomplete is disabled at the form level, then we might want to show |
374 // a warning in place of suggestions. However, if autocomplete is disabled | 406 // a warning in place of suggestions. However, if autocomplete is disabled |
375 // specifically for this field, we never want to show a warning. Otherwise, | 407 // specifically for this field, we never want to show a warning. Otherwise, |
376 // we might interfere with custom popups (e.g. search suggestions) used by | 408 // we might interfere with custom popups (e.g. search suggestions) used by |
377 // the website. | 409 // the website. |
378 const WebFormElement form = element.form(); | 410 const WebFormElement form = element.form(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 autofill_query_id_ = query_counter++; | 467 autofill_query_id_ = query_counter++; |
436 | 468 |
437 webkit::forms::FormData form; | 469 webkit::forms::FormData form; |
438 webkit::forms::FormField field; | 470 webkit::forms::FormField field; |
439 if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form, | 471 if (!FindFormAndFieldForInputElement(node.toConst<WebInputElement>(), &form, |
440 &field, REQUIRE_AUTOCOMPLETE)) { | 472 &field, REQUIRE_AUTOCOMPLETE)) { |
441 return; | 473 return; |
442 } | 474 } |
443 | 475 |
444 autofill_action_ = action; | 476 autofill_action_ = action; |
445 was_query_node_autofilled_ = field.is_autofilled; | |
446 Send(new AutofillHostMsg_FillAutofillFormData( | 477 Send(new AutofillHostMsg_FillAutofillFormData( |
447 routing_id(), autofill_query_id_, form, field, unique_id)); | 478 routing_id(), autofill_query_id_, form, field, unique_id)); |
448 } | 479 } |
449 | 480 |
| 481 void AutofillAgent::SetNodeText(const string16& value, |
| 482 WebKit::WebInputElement* node) { |
| 483 string16 substring = value; |
| 484 substring = substring.substr(0, node->maxLength()); |
| 485 |
| 486 node->setValue(substring, true); |
| 487 } |
| 488 |
450 } // namespace autofill | 489 } // namespace autofill |
OLD | NEW |