Commit 2468468c authored by Maria Kazinova's avatar Maria Kazinova Committed by Commit Bot

[iOS] Using numeric renderer IDs for Autofill active field filling.

Bug: 1075444, 1131038
Change-Id: I925317fd7667be5b94f1c74565e82f7df896ffd5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2416079Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Commit-Queue: Maria Kazinova <kazinova@google.com>
Cr-Commit-Position: refs/heads/master@{#812158}
parent 847a372a
......@@ -71,6 +71,7 @@ using autofill::FormRendererId;
using autofill::FieldDataManager;
using autofill::FieldRendererId;
using autofill::FieldPropertiesFlags::kAutofilledOnUserTrigger;
using autofill::kNotSetRendererID;
namespace {
......@@ -904,6 +905,8 @@ autofillManagerFromWebState:(web::WebState*)webState
value:(const base::string16)value
inFrame:(web::WebFrame*)frame {
auto data = std::make_unique<base::DictionaryValue>();
data->SetInteger("unique_renderer_id",
uniqueFieldID ? uniqueFieldID.value() : kNotSetRendererID);
data->SetString("identifier", fieldIdentifier);
data->SetString("form", formName);
data->SetString("value", value);
......
......@@ -69,10 +69,17 @@ using autofill::FieldRendererId;
inFrame:(web::WebFrame*)frame
completionHandler:(void (^)(BOOL))completionHandler {
DCHECK(data);
bool useRendererIDs = base::FeatureList::IsEnabled(
autofill::features::kAutofillUseUniqueRendererIDsOnIOS);
std::string fillingFunction =
useRendererIDs ? "autofill.fillActiveFormFieldUsingRendererIDs"
: "autofill.fillActiveFormField";
std::vector<base::Value> parameters;
parameters.push_back(std::move(*data));
autofill::ExecuteJavaScriptFunction(
"autofill.fillActiveFormField", parameters, frame,
fillingFunction, parameters, frame,
autofill::CreateBoolCallback(completionHandler));
}
......
......@@ -160,10 +160,11 @@ __gCrWeb.autofill['extractForms'] = function(
};
/**
* Fills data into the active form field.
* Fills data into the active form field. Logic uses string identifiers.
*
* @param {AutofillFormFieldData} data The data to fill in.
* @return {boolean} Whether the field was filled successfully.
* TODO(crbug/1131038): Remove once using renderer IDs is launched.
*/
__gCrWeb.autofill['fillActiveFormField'] = function(data) {
const activeElement = document.activeElement;
......@@ -174,6 +175,23 @@ __gCrWeb.autofill['fillActiveFormField'] = function(data) {
return __gCrWeb.autofill.fillFormField(data, activeElement);
};
/**
* Fills data into the active form field. Logic uses unique renderer IDs.
*
* @param {AutofillFormFieldData} data The data to fill in.
* @return {boolean} Whether the field was filled successfully.
*/
__gCrWeb.autofill['fillActiveFormFieldUsingRendererIDs'] = function(data) {
const activeElement = document.activeElement;
const fieldID = data['unique_renderer_id'];
if (typeof fieldID === 'undefined' ||
fieldID.toString() !== __gCrWeb.fill.getUniqueID(activeElement)) {
return false;
}
__gCrWeb.autofill.lastAutoFilledElement = activeElement;
return __gCrWeb.autofill.fillFormField(data, activeElement);
};
// Remove Autofill styling when control element is edited by the user.
function controlElementInputListener_(evt) {
if (evt.isTrusted) {
......
......@@ -1777,6 +1777,7 @@ TEST_F(AutofillControllerJsTest, ExtractForms) {
}];
}
// TODO(crbug/1131038): Remove once using renderer IDs is launched.
TEST_F(AutofillControllerJsTest, FillActiveFormField) {
LoadHtml(kHTMLForTestingElements);
......@@ -1805,6 +1806,39 @@ TEST_F(AutofillControllerJsTest, FillActiveFormField) {
<< "A non-form element's value should changed.";
}
TEST_F(AutofillControllerJsTest, FillActiveFormFieldUsingRendererIDs) {
LoadHtml(kHTMLForTestingElements);
ExecuteJavaScript(@"__gCrWeb.fill.setUpForUniqueIDs(0);");
// Simulate form parsing to set renderer IDs.
ExecuteJavaScript(@"__gCrWeb.autofill.extractForms(0, true)");
NSString* newValue = @"new value";
EXPECT_NSEQ(
newValue,
ExecuteJavaScriptWithFormat(
@"var element=document.getElementsByName('lastname')[0];"
"element.focus();"
"var "
"data={\"name\":\"lastname\",\"value\":\"%@\","
"\"identifier\":\"lastname\",\"unique_renderer_id\":2};"
"__gCrWeb.autofill.fillActiveFormFieldUsingRendererIDs(data);"
"element.value",
newValue));
EXPECT_NSEQ(
@YES, ExecuteJavaScriptWithFormat(
@"var element=document.getElementsByName('gl')[0];"
"element.focus();"
"var oldValue = element.value;"
"var "
"data={\"name\":\"lastname\",\"value\":\"%@\","
"\"identifier\":\"lastname\",\"unique_renderer_id\":2};"
"__gCrWeb.autofill.fillActiveFormFieldUsingRendererIDs(data);"
"element.value === oldValue",
newValue))
<< "A non-form element's value should changed.";
}
// iOS version of FormAutofillTest.FormCache_ExtractNewForms from
// chrome/renderer/autofill/form_autofill_browsertest.cc
TEST_F(AutofillControllerJsTest, ExtractNewForms) {
......
......@@ -371,6 +371,7 @@ TEST_F(JsAutofillManagerTest, FillActiveFormField) {
@"<html><body><form name='testform' method='post'>"
"<input type='email' id='email' name='email'/>"
"</form></body></html>");
RunFormsSearch();
NSString* get_element_javascript = @"document.getElementsByName('email')[0]";
NSString* focus_element_javascript =
......@@ -379,6 +380,7 @@ TEST_F(JsAutofillManagerTest, FillActiveFormField) {
auto data = std::make_unique<base::DictionaryValue>();
data->SetString("name", "email");
data->SetString("identifier", "email");
data->SetInteger("unique_renderer_id", 1);
data->SetString("value", "newemail@com");
__block BOOL success = NO;
[manager_ fillActiveFormField:std::move(data)
......@@ -620,16 +622,20 @@ TEST_F(JsAutofillManagerTest, ClearForm) {
"</form></body></html>");
RunFormsSearch();
std::vector<std::pair<NSString*, int>> field_ids = {{@"firstname", 1},
{@"email", 2}};
// Fill form fields.
for (NSString* field : {@"firstname", @"email"}) {
NSString* getFieldScript = [NSString
stringWithFormat:@"document.getElementsByName('%@')[0]", field];
for (auto& field_data : field_ids) {
NSString* getFieldScript =
[NSString stringWithFormat:@"document.getElementsByName('%@')[0]",
field_data.first];
NSString* focusScript =
[NSString stringWithFormat:@"%@.focus()", getFieldScript];
ExecuteJavaScript(focusScript);
auto data = std::make_unique<base::DictionaryValue>();
data->SetString("name", SysNSStringToUTF8(field));
data->SetString("identifier", SysNSStringToUTF8(field));
data->SetString("name", SysNSStringToUTF8(field_data.first));
data->SetString("identifier", SysNSStringToUTF8(field_data.first));
data->SetInteger("unique_renderer_id", field_data.second);
data->SetString("value", "testvalue");
__block BOOL success = NO;
[manager_ fillActiveFormField:std::move(data)
......
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