| 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/core/browser/autofill_external_delegate.h" | 5 #include "components/autofill/core/browser/autofill_external_delegate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 80 |
| 81 query_form_ = form; | 81 query_form_ = form; |
| 82 query_field_ = field; | 82 query_field_ = field; |
| 83 display_warning_if_disabled_ = display_warning_if_disabled; | 83 display_warning_if_disabled_ = display_warning_if_disabled; |
| 84 query_id_ = query_id; | 84 query_id_ = query_id; |
| 85 element_bounds_ = element_bounds; | 85 element_bounds_ = element_bounds; |
| 86 } | 86 } |
| 87 | 87 |
| 88 void AutofillExternalDelegate::OnSuggestionsReturned( | 88 void AutofillExternalDelegate::OnSuggestionsReturned( |
| 89 int query_id, | 89 int query_id, |
| 90 const std::vector<base::string16>& suggested_values, | 90 const std::vector<Suggestion>& input_suggestions) { |
| 91 const std::vector<base::string16>& suggested_labels, | |
| 92 const std::vector<base::string16>& suggested_icons, | |
| 93 const std::vector<int>& suggested_unique_ids) { | |
| 94 if (query_id != query_id_) | 91 if (query_id != query_id_) |
| 95 return; | 92 return; |
| 96 | 93 |
| 97 std::vector<base::string16> values(suggested_values); | 94 std::vector<Suggestion> suggestions(input_suggestions); |
| 98 std::vector<base::string16> labels(suggested_labels); | |
| 99 std::vector<base::string16> icons(suggested_icons); | |
| 100 std::vector<int> ids(suggested_unique_ids); | |
| 101 | 95 |
| 102 // Add or hide warnings as appropriate. | 96 // Add or hide warnings as appropriate. |
| 103 ApplyAutofillWarnings(&values, &labels, &icons, &ids); | 97 ApplyAutofillWarnings(&suggestions); |
| 104 | 98 |
| 105 // Add a separator to go between the values and menu items. | 99 // Add a separator to go between the values and menu items. |
| 106 values.push_back(base::string16()); | 100 suggestions.push_back(Suggestion()); |
| 107 labels.push_back(base::string16()); | 101 suggestions.back().frontend_id = POPUP_ITEM_ID_SEPARATOR; |
| 108 icons.push_back(base::string16()); | |
| 109 ids.push_back(POPUP_ITEM_ID_SEPARATOR); | |
| 110 | 102 |
| 111 if (manager_->ShouldShowScanCreditCard(query_form_, query_field_)) { | 103 if (manager_->ShouldShowScanCreditCard(query_form_, query_field_)) { |
| 112 values.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD)); | 104 Suggestion scan_credit_card( |
| 113 labels.push_back(base::string16()); | 105 l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD)); |
| 114 icons.push_back(base::string16()); | 106 scan_credit_card.frontend_id = POPUP_ITEM_ID_SCAN_CREDIT_CARD; |
| 115 ids.push_back(POPUP_ITEM_ID_SCAN_CREDIT_CARD); | 107 suggestions.push_back(scan_credit_card); |
| 116 } | 108 } |
| 117 | 109 |
| 118 // Only include "Autofill Options" special menu item if we have Autofill | 110 // Only include "Autofill Options" special menu item if we have Autofill |
| 119 // suggestions. | 111 // suggestions. |
| 120 has_suggestion_ = false; | 112 has_suggestion_ = false; |
| 121 for (size_t i = 0; i < ids.size(); ++i) { | 113 for (size_t i = 0; i < suggestions.size(); ++i) { |
| 122 if (ids[i] > 0) { | 114 if (suggestions[i].frontend_id > 0) { |
| 123 has_suggestion_ = true; | 115 has_suggestion_ = true; |
| 124 break; | 116 break; |
| 125 } | 117 } |
| 126 } | 118 } |
| 127 | 119 |
| 128 if (has_suggestion_) | 120 if (has_suggestion_) |
| 129 ApplyAutofillOptions(&values, &labels, &icons, &ids); | 121 ApplyAutofillOptions(&suggestions); |
| 130 | 122 |
| 131 // Remove the separator if it is the last element. | 123 // Remove the separator if it is the last element. |
| 132 DCHECK_GT(ids.size(), 0U); | 124 DCHECK_GT(suggestions.size(), 0U); |
| 133 if (ids.back() == POPUP_ITEM_ID_SEPARATOR) { | 125 if (suggestions.back().frontend_id == POPUP_ITEM_ID_SEPARATOR) |
| 134 values.pop_back(); | 126 suggestions.pop_back(); |
| 135 labels.pop_back(); | |
| 136 icons.pop_back(); | |
| 137 ids.pop_back(); | |
| 138 } | |
| 139 | 127 |
| 140 // If anything else is added to modify the values after inserting the data | 128 // If anything else is added to modify the values after inserting the data |
| 141 // list, AutofillPopupControllerImpl::UpdateDataListValues will need to be | 129 // list, AutofillPopupControllerImpl::UpdateDataListValues will need to be |
| 142 // updated to match. | 130 // updated to match. |
| 143 InsertDataListValues(&values, &labels, &icons, &ids); | 131 InsertDataListValues(&suggestions); |
| 144 | 132 |
| 145 #if defined(OS_MACOSX) && !defined(OS_IOS) | 133 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 146 if (values.empty() && | 134 if (values.empty() && |
| 147 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, | 135 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, |
| 148 query_field_)) { | 136 query_field_)) { |
| 149 values.push_back( | 137 Suggestion mac_contacts( |
| 150 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); | 138 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS); |
| 151 labels.push_back(base::string16()); | 139 mac_contacts.icon = base::ASCIIToUTF16("macContactsIcon"); |
| 152 icons.push_back(base::ASCIIToUTF16("macContactsIcon")); | 140 mac_contacts.frontend_id = POPUP_ITEM_ID_MAC_ACCESS_CONTACTS; |
| 153 ids.push_back(POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); | |
| 154 | 141 |
| 155 if (!has_shown_address_book_prompt) { | 142 if (!has_shown_address_book_prompt) { |
| 156 has_shown_address_book_prompt = true; | 143 has_shown_address_book_prompt = true; |
| 157 EmitHistogram(SHOWED_ACCESS_ADDRESS_BOOK_ENTRY); | 144 EmitHistogram(SHOWED_ACCESS_ADDRESS_BOOK_ENTRY); |
| 158 manager_->ShowedAccessAddressBookPrompt(); | 145 manager_->ShowedAccessAddressBookPrompt(); |
| 159 } | 146 } |
| 160 } | 147 } |
| 161 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 148 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 162 | 149 |
| 163 if (values.empty()) { | 150 if (suggestions.empty()) { |
| 164 // No suggestions, any popup currently showing is obsolete. | 151 // No suggestions, any popup currently showing is obsolete. |
| 165 manager_->client()->HideAutofillPopup(); | 152 manager_->client()->HideAutofillPopup(); |
| 166 return; | 153 return; |
| 167 } | 154 } |
| 168 | 155 |
| 169 // Send to display. | 156 // Send to display. |
| 170 if (query_field_.is_focusable) { | 157 if (query_field_.is_focusable) { |
| 171 manager_->client()->ShowAutofillPopup(element_bounds_, | 158 manager_->client()->ShowAutofillPopup(element_bounds_, |
| 172 query_field_.text_direction, | 159 query_field_.text_direction, |
| 173 values, | 160 suggestions, |
| 174 labels, | |
| 175 icons, | |
| 176 ids, | |
| 177 GetWeakPtr()); | 161 GetWeakPtr()); |
| 178 } | 162 } |
| 179 } | 163 } |
| 180 | 164 |
| 181 void AutofillExternalDelegate::SetCurrentDataListValues( | 165 void AutofillExternalDelegate::SetCurrentDataListValues( |
| 182 const std::vector<base::string16>& data_list_values, | 166 const std::vector<base::string16>& data_list_values, |
| 183 const std::vector<base::string16>& data_list_labels) { | 167 const std::vector<base::string16>& data_list_labels) { |
| 184 data_list_values_ = data_list_values; | 168 data_list_values_ = data_list_values; |
| 185 data_list_labels_ = data_list_labels; | 169 data_list_labels_ = data_list_labels; |
| 186 | 170 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 DCHECK(driver_->RendererIsAvailable()); | 312 DCHECK(driver_->RendererIsAvailable()); |
| 329 // Fill the values for the whole form. | 313 // Fill the values for the whole form. |
| 330 manager_->FillOrPreviewForm(renderer_action, | 314 manager_->FillOrPreviewForm(renderer_action, |
| 331 query_id_, | 315 query_id_, |
| 332 query_form_, | 316 query_form_, |
| 333 query_field_, | 317 query_field_, |
| 334 unique_id); | 318 unique_id); |
| 335 } | 319 } |
| 336 | 320 |
| 337 void AutofillExternalDelegate::ApplyAutofillWarnings( | 321 void AutofillExternalDelegate::ApplyAutofillWarnings( |
| 338 std::vector<base::string16>* values, | 322 std::vector<Suggestion>* suggestions) { |
| 339 std::vector<base::string16>* labels, | |
| 340 std::vector<base::string16>* icons, | |
| 341 std::vector<int>* unique_ids) { | |
| 342 if (!ShouldAutofill(query_field_)) { | 323 if (!ShouldAutofill(query_field_)) { |
| 343 // Autofill is disabled. If there were some profile or credit card | 324 // Autofill is disabled. If there were some profile or credit card |
| 344 // suggestions to show, show a warning instead. Otherwise, clear out the | 325 // suggestions to show, show a warning instead. Otherwise, clear out the |
| 345 // list of suggestions. | 326 // list of suggestions. |
| 346 if (!unique_ids->empty() && (*unique_ids)[0] > 0) { | 327 if (!suggestions->empty() && (*suggestions)[0].frontend_id > 0) { |
| 347 // If Autofill is disabled and we had suggestions, show a warning instead. | 328 // If Autofill is disabled and we had suggestions, show a warning instead. |
| 348 values->assign( | 329 suggestions->assign(1, Suggestion( |
| 349 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); | 330 l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED))); |
| 350 labels->assign(1, base::string16()); | 331 (*suggestions)[0].frontend_id = POPUP_ITEM_ID_WARNING_MESSAGE; |
| 351 icons->assign(1, base::string16()); | |
| 352 unique_ids->assign(1, POPUP_ITEM_ID_WARNING_MESSAGE); | |
| 353 } else { | 332 } else { |
| 354 values->clear(); | 333 suggestions->clear(); |
| 355 labels->clear(); | |
| 356 icons->clear(); | |
| 357 unique_ids->clear(); | |
| 358 } | 334 } |
| 359 } else if (unique_ids->size() > 1 && | 335 } else if (suggestions->size() > 1 && |
| 360 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE) { | 336 (*suggestions)[0].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE) { |
| 361 // If we received a warning instead of suggestions from Autofill but regular | 337 // If we received a warning instead of suggestions from Autofill but regular |
| 362 // suggestions from autocomplete, don't show the Autofill warning. | 338 // suggestions from autocomplete, don't show the Autofill warning. |
| 363 values->erase(values->begin()); | 339 suggestions->erase(suggestions->begin()); |
| 364 labels->erase(labels->begin()); | |
| 365 icons->erase(icons->begin()); | |
| 366 unique_ids->erase(unique_ids->begin()); | |
| 367 } | 340 } |
| 368 | 341 |
| 369 // If we were about to show a warning and we shouldn't, don't. | 342 // If we were about to show a warning and we shouldn't, don't. |
| 370 if (!unique_ids->empty() && | 343 if (!suggestions->empty() && |
| 371 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE && | 344 (*suggestions)[0].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE && |
| 372 !display_warning_if_disabled_) { | 345 !display_warning_if_disabled_) { |
| 373 values->clear(); | 346 suggestions->clear(); |
| 374 labels->clear(); | |
| 375 icons->clear(); | |
| 376 unique_ids->clear(); | |
| 377 } | 347 } |
| 378 } | 348 } |
| 379 | 349 |
| 380 void AutofillExternalDelegate::ApplyAutofillOptions( | 350 void AutofillExternalDelegate::ApplyAutofillOptions( |
| 381 std::vector<base::string16>* values, | 351 std::vector<Suggestion>* suggestions) { |
| 382 std::vector<base::string16>* labels, | |
| 383 std::vector<base::string16>* icons, | |
| 384 std::vector<int>* unique_ids) { | |
| 385 // The form has been auto-filled, so give the user the chance to clear the | 352 // The form has been auto-filled, so give the user the chance to clear the |
| 386 // form. Append the 'Clear form' menu item. | 353 // form. Append the 'Clear form' menu item. |
| 387 if (query_field_.is_autofilled) { | 354 if (query_field_.is_autofilled) { |
| 388 values->push_back( | 355 suggestions->push_back(Suggestion( |
| 389 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM)); | 356 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM))); |
| 390 labels->push_back(base::string16()); | 357 suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM; |
| 391 icons->push_back(base::string16()); | |
| 392 unique_ids->push_back(POPUP_ITEM_ID_CLEAR_FORM); | |
| 393 } | 358 } |
| 394 | 359 |
| 395 // Append the 'Chrome Autofill options' menu item; | 360 // Append the 'Chrome Autofill options' menu item; |
| 396 values->push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP)); | 361 suggestions->push_back(Suggestion( |
| 397 labels->push_back(base::string16()); | 362 l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP))); |
| 398 icons->push_back(base::string16()); | 363 suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS; |
| 399 unique_ids->push_back(POPUP_ITEM_ID_AUTOFILL_OPTIONS); | |
| 400 } | 364 } |
| 401 | 365 |
| 402 void AutofillExternalDelegate::InsertDataListValues( | 366 void AutofillExternalDelegate::InsertDataListValues( |
| 403 std::vector<base::string16>* values, | 367 std::vector<Suggestion>* suggestions) { |
| 404 std::vector<base::string16>* labels, | |
| 405 std::vector<base::string16>* icons, | |
| 406 std::vector<int>* unique_ids) { | |
| 407 if (data_list_values_.empty()) | 368 if (data_list_values_.empty()) |
| 408 return; | 369 return; |
| 409 | 370 |
| 410 // Insert the separator between the datalist and Autofill values (if there | 371 // Insert the separator between the datalist and Autofill values (if there |
| 411 // are any). | 372 // are any). |
| 412 if (!values->empty()) { | 373 if (!suggestions->empty()) { |
| 413 values->insert(values->begin(), base::string16()); | 374 suggestions->insert(suggestions->begin(), Suggestion()); |
| 414 labels->insert(labels->begin(), base::string16()); | 375 (*suggestions)[0].frontend_id = POPUP_ITEM_ID_SEPARATOR; |
| 415 icons->insert(icons->begin(), base::string16()); | |
| 416 unique_ids->insert(unique_ids->begin(), POPUP_ITEM_ID_SEPARATOR); | |
| 417 } | 376 } |
| 418 | 377 |
| 419 // Insert the datalist elements. | 378 // Insert the datalist elements at the beginning. |
| 420 values->insert(values->begin(), | 379 suggestions->insert(suggestions->begin(), data_list_values_.size(), |
| 421 data_list_values_.begin(), | 380 Suggestion()); |
| 422 data_list_values_.end()); | 381 for (size_t i = 0; i < data_list_values_.size(); i++) { |
| 423 labels->insert(labels->begin(), | 382 (*suggestions)[i].value = data_list_values_[i]; |
| 424 data_list_labels_.begin(), | 383 (*suggestions)[i].label = data_list_labels_[i]; |
| 425 data_list_labels_.end()); | 384 (*suggestions)[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY; |
| 426 | 385 } |
| 427 // Set the values that all datalist elements share. | |
| 428 icons->insert(icons->begin(), | |
| 429 data_list_values_.size(), | |
| 430 base::string16()); | |
| 431 unique_ids->insert(unique_ids->begin(), | |
| 432 data_list_values_.size(), | |
| 433 POPUP_ITEM_ID_DATALIST_ENTRY); | |
| 434 } | 386 } |
| 435 | 387 |
| 436 #if defined(OS_MACOSX) && !defined(OS_IOS) | 388 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 437 void AutofillExternalDelegate::PingRenderer() { | 389 void AutofillExternalDelegate::PingRenderer() { |
| 438 driver_->PingRenderer(); | 390 driver_->PingRenderer(); |
| 439 } | 391 } |
| 440 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 392 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 441 | 393 |
| 442 } // namespace autofill | 394 } // namespace autofill |
| OLD | NEW |