Commit 09d373f7 authored by jdonnelly's avatar jdonnelly Committed by Commit bot

Add upstream bits necessary for iOS card unmask prompt.

See https://chromereviews.googleplex.com/193957013/ for the associated downstream changes.

BUG=484806

Review URL: https://codereview.chromium.org/1137403002

Cr-Commit-Position: refs/heads/master@{#330529}
parent cd4cce34
...@@ -551,6 +551,12 @@ bool AutofillManager::WillFillCreditCardNumber(const FormData& form, ...@@ -551,6 +551,12 @@ bool AutofillManager::WillFillCreditCardNumber(const FormData& form,
if (autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER) if (autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER)
return true; return true;
#if defined(OS_IOS)
// On iOS, we only fill out one field at a time. So we only need to check the
// current field.
return false;
#endif
// If the relevant section is already autofilled, the new fill operation will // If the relevant section is already autofilled, the new fill operation will
// only fill |autofill_field|. // only fill |autofill_field|.
if (SectionIsAutofilled(*form_structure, form, autofill_field->section())) if (SectionIsAutofilled(*form_structure, form, autofill_field->section()))
......
...@@ -1513,15 +1513,26 @@ TEST_F(AutofillManagerTest, WillFillCreditCardNumber) { ...@@ -1513,15 +1513,26 @@ TEST_F(AutofillManagerTest, WillFillCreditCardNumber) {
month_field = &form.fields[i]; month_field = &form.fields[i];
} }
// Empty form - whole form is Autofilled. // Empty form - whole form is Autofilled (except on iOS).
EXPECT_TRUE(WillFillCreditCardNumber(form, *number_field)); EXPECT_TRUE(WillFillCreditCardNumber(form, *number_field));
#if defined(OS_IOS)
EXPECT_FALSE(WillFillCreditCardNumber(form, *name_field));
#else
EXPECT_TRUE(WillFillCreditCardNumber(form, *name_field)); EXPECT_TRUE(WillFillCreditCardNumber(form, *name_field));
#endif // defined(OS_IOS)
// If the user has entered a value, it won't be overridden. // If the user has entered a value, it won't be overridden.
number_field->value = ASCIIToUTF16("gibberish"); number_field->value = ASCIIToUTF16("gibberish");
EXPECT_TRUE(WillFillCreditCardNumber(form, *number_field)); EXPECT_TRUE(WillFillCreditCardNumber(form, *number_field));
EXPECT_FALSE(WillFillCreditCardNumber(form, *name_field)); EXPECT_FALSE(WillFillCreditCardNumber(form, *name_field));
// But if that value is removed, it will be Autofilled (except on iOS).
number_field->value.clear(); number_field->value.clear();
#if defined(OS_IOS)
EXPECT_FALSE(WillFillCreditCardNumber(form, *name_field));
#else
EXPECT_TRUE(WillFillCreditCardNumber(form, *name_field)); EXPECT_TRUE(WillFillCreditCardNumber(form, *name_field));
#endif // defined(OS_IOS)
// When part of the section is Autofilled, only fill the initiating field. // When part of the section is Autofilled, only fill the initiating field.
month_field->is_autofilled = true; month_field->is_autofilled = true;
...@@ -3192,11 +3203,29 @@ TEST_F(AutofillManagerTest, DontOfferToSaveWalletCard) { ...@@ -3192,11 +3203,29 @@ TEST_F(AutofillManagerTest, DontOfferToSaveWalletCard) {
card.SetTypeForMaskedCard(kVisaCard); card.SetTypeForMaskedCard(kVisaCard);
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCard(_)).Times(0); EXPECT_CALL(autofill_client_, ConfirmSaveCreditCard(_)).Times(0);
#if defined(OS_IOS)
EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _)).Times(4);
#else
EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _)); EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _));
#endif // defined(OS_IOS)
autofill_manager_->FillOrPreviewCreditCardForm( autofill_manager_->FillOrPreviewCreditCardForm(
AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form, AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
form.fields[0], card, 0); form.fields[0], card, 0);
#if defined(OS_IOS)
// Filling out the entire form on iOS requires requesting autofill on each of
// the form fields.
autofill_manager_->FillOrPreviewCreditCardForm(
AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
form.fields[1], card, 0);
autofill_manager_->FillOrPreviewCreditCardForm(
AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
form.fields[2], card, 0);
autofill_manager_->FillOrPreviewCreditCardForm(
AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
form.fields[3], card, 0);
#endif // defined(OS_IOS)
// Manually fill out |form| so we can use it in OnFormSubmitted. // Manually fill out |form| so we can use it in OnFormSubmitted.
for (size_t i = 0; i < form.fields.size(); ++i) { for (size_t i = 0; i < form.fields.size(); ++i) {
if (form.fields[i].name == ASCIIToUTF16("cardnumber")) if (form.fields[i].name == ASCIIToUTF16("cardnumber"))
...@@ -3225,7 +3254,7 @@ TEST_F(AutofillManagerTest, DontOfferToSaveWalletCard) { ...@@ -3225,7 +3254,7 @@ TEST_F(AutofillManagerTest, DontOfferToSaveWalletCard) {
} }
autofill_manager_->FillOrPreviewCreditCardForm( autofill_manager_->FillOrPreviewCreditCardForm(
AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form, AutofillDriver::FORM_DATA_ACTION_FILL, kDefaultPageID, form,
form.fields[0], card, 0); form.fields[1], card, 0);
autofill_manager_->OnUnmaskResponse(response); autofill_manager_->OnUnmaskResponse(response);
autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS,
"4012888888881881"); "4012888888881881");
......
...@@ -1310,7 +1310,7 @@ TEST_F(AutofillMetricsTest, CreditCardSelectedFormEvents) { ...@@ -1310,7 +1310,7 @@ TEST_F(AutofillMetricsTest, CreditCardSelectedFormEvents) {
"10000000-0000-0000-0000-000000000002", 0); // masked server card "10000000-0000-0000-0000-000000000002", 0); // masked server card
autofill_manager_->FillOrPreviewForm( autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, AutofillDriver::FORM_DATA_ACTION_FILL,
0, form, form.fields.front(), 0, form, form.fields[2],
autofill_manager_->MakeFrontendID(guid, SuggestionBackendID())); autofill_manager_->MakeFrontendID(guid, SuggestionBackendID()));
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard", "Autofill.FormEvents.CreditCard",
...@@ -1332,11 +1332,11 @@ TEST_F(AutofillMetricsTest, CreditCardSelectedFormEvents) { ...@@ -1332,11 +1332,11 @@ TEST_F(AutofillMetricsTest, CreditCardSelectedFormEvents) {
"10000000-0000-0000-0000-000000000002", 0); // masked server card "10000000-0000-0000-0000-000000000002", 0); // masked server card
autofill_manager_->FillOrPreviewForm( autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, AutofillDriver::FORM_DATA_ACTION_FILL,
0, form, form.fields.front(), 0, form, form.fields[2],
autofill_manager_->MakeFrontendID(guid, SuggestionBackendID())); autofill_manager_->MakeFrontendID(guid, SuggestionBackendID()));
autofill_manager_->FillOrPreviewForm( autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, AutofillDriver::FORM_DATA_ACTION_FILL,
0, form, form.fields.front(), 0, form, form.fields[2],
autofill_manager_->MakeFrontendID(guid, SuggestionBackendID())); autofill_manager_->MakeFrontendID(guid, SuggestionBackendID()));
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard", "Autofill.FormEvents.CreditCard",
......
...@@ -23,8 +23,17 @@ ...@@ -23,8 +23,17 @@
minimumRequiredFieldsCount:(NSUInteger)requiredFieldsCount minimumRequiredFieldsCount:(NSUInteger)requiredFieldsCount
completionHandler:(void (^)(NSString*))completionHandler; completionHandler:(void (^)(NSString*))completionHandler;
// Stores the current active element. This is used to make the element active
// again in case the web view loses focus when a dialog is presented over it.
- (void)storeActiveElement;
// Clears the current active element.
- (void)clearActiveElement;
// Fills the data in JSON string |dataString| into the active form field, then // Fills the data in JSON string |dataString| into the active form field, then
// executes the |completionHandler|. // executes the |completionHandler|. The active form field is either
// document.activeElement or the field stored by a call to storeActiveElement.
// non-null.
- (void)fillActiveFormField:(NSString*)dataString - (void)fillActiveFormField:(NSString*)dataString
completionHandler:(ProceduralBlock)completionHandler; completionHandler:(ProceduralBlock)completionHandler;
......
...@@ -47,6 +47,16 @@ ...@@ -47,6 +47,16 @@
return @"__gCrWeb.autofill"; return @"__gCrWeb.autofill";
} }
- (void)storeActiveElement {
NSString* js = @"__gCrWeb.autofill.storeActiveElement()";
[self evaluate:js stringResultHandler:nil];
}
- (void)clearActiveElement {
NSString* js = @"__gCrWeb.autofill.clearActiveElement()";
[self evaluate:js stringResultHandler:nil];
}
- (void)fillActiveFormField:(NSString*)dataString - (void)fillActiveFormField:(NSString*)dataString
completionHandler:(ProceduralBlock)completionHandler { completionHandler:(ProceduralBlock)completionHandler {
web::JavaScriptCompletion resultHandler = ^void(NSString*, NSError*) { web::JavaScriptCompletion resultHandler = ^void(NSString*, NSError*) {
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
// representing an array of objects, each of which represents an Autofill form // representing an array of objects, each of which represents an Autofill form
// with information about a form to be filled and/or submitted and it can be // with information about a form to be filled and/or submitted and it can be
// translated to struct FormData // translated to struct FormData
// (chromium/src/components/autofill/common/form_data.h) for further processing. // (chromium/src/components/autofill/core/common/form_data.h) for further
// processing.
/** /**
* Namespace for this file. It depends on |__gCrWeb| having already been * Namespace for this file. It depends on |__gCrWeb| having already been
...@@ -97,6 +98,11 @@ __gCrWeb.autofill.EXTRACT_MASK_OPTIONS = 1 << 2; ...@@ -97,6 +98,11 @@ __gCrWeb.autofill.EXTRACT_MASK_OPTIONS = 1 << 2;
*/ */
__gCrWeb.autofill.lastAutoFilledElement = null; __gCrWeb.autofill.lastAutoFilledElement = null;
/**
* The last element that was active (used to restore focus if necessary).
*/
__gCrWeb.autofill.lastActiveElement = null;
/** /**
* Scans DOM and returns a JSON string representation of forms and form * Scans DOM and returns a JSON string representation of forms and form
* extraction results. * extraction results.
...@@ -126,12 +132,34 @@ __gCrWeb.autofill['extractForms'] = function(requiredFields, requirements) { ...@@ -126,12 +132,34 @@ __gCrWeb.autofill['extractForms'] = function(requiredFields, requirements) {
}; };
/** /**
* Fills data into the active form field. * Stores the current active element. This is used to make the element active
* again in case the web view loses focus when a dialog is presented over it.
*/
__gCrWeb.autofill['storeActiveElement'] = function() {
__gCrWeb.autofill.lastActiveElement = document.activeElement;
}
/**
* Clears the current active element by setting it to null.
*/
__gCrWeb.autofill['clearActiveElement'] = function() {
__gCrWeb.autofill.lastActiveElement = null;
}
/**
* Fills data into the active form field. The active form field is either
* document.activeElement or the value of lastActiveElement if that value is
* non-null.
* *
* @param {Object} data The data to fill in. * @param {Object} data The data to fill in.
*/ */
__gCrWeb.autofill['fillActiveFormField'] = function(data) { __gCrWeb.autofill['fillActiveFormField'] = function(data) {
var activeElement = document.activeElement; var activeElement = document.activeElement;
if (__gCrWeb.autofill.lastActiveElement) {
activeElement = __gCrWeb.autofill.lastActiveElement;
activeElement.focus();
__gCrWeb.autofill.lastActiveElement = null;
}
if (data['name'] !== __gCrWeb['common'].nameForAutofill(activeElement)) { if (data['name'] !== __gCrWeb['common'].nameForAutofill(activeElement)) {
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment