Commit 7f9ae285 authored by Maria Kazinova's avatar Maria Kazinova Committed by Commit Bot

[iOS] Using numeric renderer IDs for Autofill form clearing.

Bug: 1075444, 1131038
Change-Id: Id5aa1c9d1e3a18d432d460c1a45878a945d018c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2435092
Commit-Queue: Maria Kazinova <kazinova@google.com>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarVadym Doroshenko  <dvadym@chromium.org>
Reviewed-by: default avatarJohn Wu <jzw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812306}
parent e4928121
...@@ -455,7 +455,9 @@ autofillManagerFromWebState:(web::WebState*)webState ...@@ -455,7 +455,9 @@ autofillManagerFromWebState:(web::WebState*)webState
__weak AutofillAgent* weakSelf = self; __weak AutofillAgent* weakSelf = self;
[_jsAutofillManager [_jsAutofillManager
clearAutofilledFieldsForFormName:formName clearAutofilledFieldsForFormName:formName
formUniqueID:uniqueFormID
fieldIdentifier:fieldIdentifier fieldIdentifier:fieldIdentifier
fieldUniqueID:uniqueFieldID
inFrame:frame inFrame:frame
completionHandler:^(NSString* jsonString) { completionHandler:^(NSString* jsonString) {
AutofillAgent* strongSelf = weakSelf; AutofillAgent* strongSelf = weakSelf;
......
...@@ -13,15 +13,29 @@ ...@@ -13,15 +13,29 @@
@interface FakeJSAutofillManager : JsAutofillManager @interface FakeJSAutofillManager : JsAutofillManager
// The name of the form that was most recently passed to // The name of the form that was most recently passed to
// |clearAutofilledFieldsForFormName:fieldIdentifier:inFrame:completionHandler:| // |clearAutofilledFieldsForFormName:formUniqueID:fieldIdentifier:
// fieldUniqueID:inFrame:completionHandler:|
@property(nonatomic, copy, readonly) NSString* lastClearedFormName; @property(nonatomic, copy, readonly) NSString* lastClearedFormName;
// The renderer ID of the form that was most recently passed to
// |clearAutofilledFieldsForFormName:formUniqueID:fieldIdentifier:
// fieldUniqueID:inFrame:completionHandler:|
@property(nonatomic, readonly) autofill::FormRendererId lastClearedFormUniqueID;
// The field identifier that was most recently passed to // The field identifier that was most recently passed to
// |clearAutofilledFieldsForFormName:fieldIdentifier:inFrame:completionHandler:| // |clearAutofilledFieldsForFormName:formUniqueID:fieldIdentifier:
// fieldUniqueID:inFrame:completionHandler:|
@property(nonatomic, copy, readonly) NSString* lastClearedFieldIdentifier; @property(nonatomic, copy, readonly) NSString* lastClearedFieldIdentifier;
// The renderer ID of the field that was most recently passed to
// |clearAutofilledFieldsForFormName:formUniqueID:fieldIdentifier:
// fieldUniqueID:inFrame:completionHandler:|
@property(nonatomic, readonly)
autofill::FieldRendererId lastClearedFieldUniqueID;
// The field identifier that was most recently passed to // The field identifier that was most recently passed to
// |clearAutofilledFieldsForFormName:fieldIdentifier:inFrame:completionHandler:| // |clearAutofilledFieldsForFormName:formUniqueID:fieldIdentifier:
// fieldUniqueID:inFrame:completionHandler:|
@property(nonatomic, copy, readonly) NSString* lastClearedFrameIdentifier; @property(nonatomic, copy, readonly) NSString* lastClearedFrameIdentifier;
@end @end
......
...@@ -18,17 +18,23 @@ ...@@ -18,17 +18,23 @@
@implementation FakeJSAutofillManager @implementation FakeJSAutofillManager
@synthesize lastClearedFormName = _lastClearedFormName; @synthesize lastClearedFormName = _lastClearedFormName;
@synthesize lastClearedFormUniqueID = _lastClearedFormUniqueID;
@synthesize lastClearedFieldIdentifier = _lastClearedFieldIdentifier; @synthesize lastClearedFieldIdentifier = _lastClearedFieldIdentifier;
@synthesize lastClearedFieldUniqueID = _lastClearedFieldUniqueID;
@synthesize lastClearedFrameIdentifier = _lastClearedFrameIdentifier; @synthesize lastClearedFrameIdentifier = _lastClearedFrameIdentifier;
- (void)clearAutofilledFieldsForFormName:(NSString*)formName - (void)
clearAutofilledFieldsForFormName:(NSString*)formName
formUniqueID:(autofill::FormRendererId)formUniqueID
fieldIdentifier:(NSString*)fieldIdentifier fieldIdentifier:(NSString*)fieldIdentifier
fieldUniqueID:(autofill::FieldRendererId)fieldUniqueID
inFrame:(web::WebFrame*)frame inFrame:(web::WebFrame*)frame
completionHandler: completionHandler:(void (^)(NSString*))completionHandler {
(void (^)(NSString*))completionHandler {
base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
_lastClearedFormName = [formName copy]; _lastClearedFormName = [formName copy];
_lastClearedFormUniqueID = formUniqueID;
_lastClearedFieldIdentifier = [fieldIdentifier copy]; _lastClearedFieldIdentifier = [fieldIdentifier copy];
_lastClearedFieldUniqueID = fieldUniqueID;
_lastClearedFrameIdentifier = _lastClearedFrameIdentifier =
frame ? base::SysUTF8ToNSString(frame->GetFrameId()) frame ? base::SysUTF8ToNSString(frame->GetFrameId())
: nil; : nil;
......
...@@ -36,8 +36,8 @@ class WebFrame; ...@@ -36,8 +36,8 @@ class WebFrame;
// Fills a number of fields in the same named form for full-form Autofill. // Fills a number of fields in the same named form for full-form Autofill.
// Applies Autofill CSS (i.e. yellow background) to filled elements. // Applies Autofill CSS (i.e. yellow background) to filled elements.
// Only empty fields will be filled, except that field named // Only empty fields will be filled, except that field named
// |forceFillFieldIdentifier| will always be filled even if non-empty. // Field identified by |forceFillFieldIdentifier|/|forceFillFieldUniqueID| will
// |forceFillFieldIdentifier| may be null. // always be filled even if non-empty. |forceFillFieldIdentifier| may be null.
// Fields must be contained in |frame|. // Fields must be contained in |frame|.
// |completionHandler| is called after the forms are filled with the JSON // |completionHandler| is called after the forms are filled with the JSON
// string containing pairs of unique renderer ids of filled fields and // string containing pairs of unique renderer ids of filled fields and
...@@ -52,12 +52,15 @@ class WebFrame; ...@@ -52,12 +52,15 @@ class WebFrame;
// currently autofilled are not modified. Field contents are cleared, and // currently autofilled are not modified. Field contents are cleared, and
// Autofill flag and styling are removed. 'change' events are sent for fields // Autofill flag and styling are removed. 'change' events are sent for fields
// whose contents changed. // whose contents changed.
// |fieldIdentifier| identifies the field that initiated the clear action. // |fieldIdentifier|/|fieldUniqueID| identify the field that initiated the clear
// |completionHandler| is called after the forms are filled with the JSON // action. |completionHandler| is called after the forms are filled with the
// string containing a list of unique renderer ids of cleared fields. // JSON string containing a list of unique renderer ids of cleared fields.
// |completionHandler| cannot be nil. // |completionHandler| cannot be nil.
- (void)clearAutofilledFieldsForFormName:(NSString*)formName - (void)
clearAutofilledFieldsForFormName:(NSString*)formName
formUniqueID:(autofill::FormRendererId)formRendererID
fieldIdentifier:(NSString*)fieldIdentifier fieldIdentifier:(NSString*)fieldIdentifier
fieldUniqueID:(autofill::FieldRendererId)fieldRendererID
inFrame:(web::WebFrame*)frame inFrame:(web::WebFrame*)frame
completionHandler:(void (^)(NSString*))completionHandler; completionHandler:(void (^)(NSString*))completionHandler;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#endif #endif
using autofill::FieldRendererId; using autofill::FieldRendererId;
using autofill::FormRendererId;
@implementation JsAutofillManager @implementation JsAutofillManager
...@@ -128,14 +129,27 @@ using autofill::FieldRendererId; ...@@ -128,14 +129,27 @@ using autofill::FieldRendererId;
} }
- (void)clearAutofilledFieldsForFormName:(NSString*)formName - (void)clearAutofilledFieldsForFormName:(NSString*)formName
formUniqueID:(FormRendererId)formRendererID
fieldIdentifier:(NSString*)fieldIdentifier fieldIdentifier:(NSString*)fieldIdentifier
fieldUniqueID:(FieldRendererId)fieldRendererID
inFrame:(web::WebFrame*)frame inFrame:(web::WebFrame*)frame
completionHandler: completionHandler:
(void (^)(NSString*))completionHandler { (void (^)(NSString*))completionHandler {
DCHECK(completionHandler); DCHECK(completionHandler);
bool useRendererIDs = base::FeatureList::IsEnabled(
autofill::features::kAutofillUseUniqueRendererIDsOnIOS);
int formNumericID =
formRendererID ? formRendererID.value() : autofill::kNotSetRendererID;
int fieldNumericID =
fieldRendererID ? fieldRendererID.value() : autofill::kNotSetRendererID;
std::vector<base::Value> parameters; std::vector<base::Value> parameters;
parameters.push_back(base::Value(base::SysNSStringToUTF8(formName))); parameters.push_back(base::Value(base::SysNSStringToUTF8(formName)));
parameters.push_back(base::Value(formNumericID));
parameters.push_back(base::Value(base::SysNSStringToUTF8(fieldIdentifier))); parameters.push_back(base::Value(base::SysNSStringToUTF8(fieldIdentifier)));
parameters.push_back(base::Value(fieldNumericID));
parameters.push_back(base::Value(useRendererIDs));
autofill::ExecuteJavaScriptFunction( autofill::ExecuteJavaScriptFunction(
"autofill.clearAutofilledFields", parameters, frame, "autofill.clearAutofilledFields", parameters, frame,
autofill::CreateStringCallback(completionHandler)); autofill::CreateStringCallback(completionHandler));
......
...@@ -329,9 +329,13 @@ __gCrWeb.autofill['fillForm'] = function( ...@@ -329,9 +329,13 @@ __gCrWeb.autofill['fillForm'] = function(
* @return {string} JSON encoded list of renderer IDs of cleared elements. * @return {string} JSON encoded list of renderer IDs of cleared elements.
*/ */
__gCrWeb.autofill['clearAutofilledFields'] = function( __gCrWeb.autofill['clearAutofilledFields'] = function(
formName, fieldIdentifier) { formName, formUniqueID, fieldIdentifier, fieldUniqueID, useRendererIDs) {
const clearedElements = []; const clearedElements = [];
const form = __gCrWeb.form.getFormElementFromIdentifier(formName);
const form = useRendererIDs ?
__gCrWeb.form.getFormElementFromUniqueFormId(formUniqueID) :
__gCrWeb.form.getFormElementFromIdentifier(formName);
const controlElements = form ? const controlElements = form ?
__gCrWeb.form.getFormControlElements(form) : __gCrWeb.form.getFormControlElements(form) :
__gCrWeb.fill.getUnownedAutofillableFormFieldElements( __gCrWeb.fill.getUnownedAutofillableFormFieldElements(
...@@ -340,8 +344,12 @@ __gCrWeb.autofill['clearAutofilledFields'] = function( ...@@ -340,8 +344,12 @@ __gCrWeb.autofill['clearAutofilledFields'] = function(
let formField = null; let formField = null;
for (let i = 0; i < controlElements.length; ++i) { for (let i = 0; i < controlElements.length; ++i) {
if (__gCrWeb.form.getFieldIdentifier(controlElements[i]) == if ((useRendererIDs &&
fieldIdentifier) { __gCrWeb.fill.getUniqueID(controlElements[i]) ==
fieldUniqueID.toString()) ||
(!useRendererIDs &&
__gCrWeb.form.getFieldIdentifier(controlElements[i]) ==
fieldIdentifier)) {
formField = controlElements[i]; formField = controlElements[i];
break; break;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#endif #endif
using autofill::FieldRendererId; using autofill::FieldRendererId;
using autofill::FormRendererId;
using base::SysNSStringToUTF8; using base::SysNSStringToUTF8;
namespace { namespace {
...@@ -612,10 +613,24 @@ TEST_F(JsAutofillManagerTest, FillFormUsingRendererIDs) { ...@@ -612,10 +613,24 @@ TEST_F(JsAutofillManagerTest, FillFormUsingRendererIDs) {
EXPECT_NSEQ(@"{\"1\":\"Cool User\",\"2\":\"coolemail@com\"}", filling_result); EXPECT_NSEQ(@"{\"1\":\"Cool User\",\"2\":\"coolemail@com\"}", filling_result);
} }
// Tests form clearing (clearAutofilledFieldsForFormName::fillIdentifier: // Tests form clearing (clearAutofilledFieldsForFormName:formUniqueID:
// inFrame:completionHandler:) method. // fieldIdentifier:fieldUniqueID:inFrame:completionHandler:) method.
// method.
TEST_F(JsAutofillManagerTest, ClearForm) { TEST_F(JsAutofillManagerTest, ClearForm) {
for (bool use_renderer_ids : {true, false}) {
SCOPED_TRACE(testing::Message()
<< "For use_renderer_ids=" << use_renderer_ids);
base::test::ScopedFeatureList scoped_feature_list;
std::vector<base::Feature> enabled_features;
std::vector<base::Feature> disabled_features;
if (use_renderer_ids) {
enabled_features.push_back(
autofill::features::kAutofillUseUniqueRendererIDsOnIOS);
} else {
disabled_features.push_back(
autofill::features::kAutofillUseUniqueRendererIDsOnIOS);
}
scoped_feature_list.InitWithFeatures(enabled_features, disabled_features);
LoadHtml(@"<html><body><form name='testform' method='post'>" LoadHtml(@"<html><body><form name='testform' method='post'>"
"<input type='text' id='firstname' name='firstname'/>" "<input type='text' id='firstname' name='firstname'/>"
"<input type='email' id='email' name='email'/>" "<input type='email' id='email' name='email'/>"
...@@ -652,7 +667,9 @@ TEST_F(JsAutofillManagerTest, ClearForm) { ...@@ -652,7 +667,9 @@ TEST_F(JsAutofillManagerTest, ClearForm) {
__block NSString* clearing_result = nil; __block NSString* clearing_result = nil;
__block BOOL block_was_called = NO; __block BOOL block_was_called = NO;
[manager_ clearAutofilledFieldsForFormName:@"testform" [manager_ clearAutofilledFieldsForFormName:@"testform"
formUniqueID:FormRendererId(0)
fieldIdentifier:@"firstname" fieldIdentifier:@"firstname"
fieldUniqueID:FieldRendererId(1)
inFrame:main_web_frame() inFrame:main_web_frame()
completionHandler:^(NSString* result) { completionHandler:^(NSString* result) {
clearing_result = [result copy]; clearing_result = [result copy];
...@@ -663,6 +680,7 @@ TEST_F(JsAutofillManagerTest, ClearForm) { ...@@ -663,6 +680,7 @@ TEST_F(JsAutofillManagerTest, ClearForm) {
return block_was_called; return block_was_called;
})); }));
EXPECT_NSEQ(@"[\"1\",\"2\"]", clearing_result); EXPECT_NSEQ(@"[\"1\",\"2\"]", clearing_result);
}
} }
} // namespace } // namespace
...@@ -181,8 +181,11 @@ using autofill::FieldRendererId; ...@@ -181,8 +181,11 @@ using autofill::FieldRendererId;
completionHandler:(nullable void (^)(void))completionHandler { completionHandler:(nullable void (^)(void))completionHandler {
web::WebFrame* frame = web::WebFrame* frame =
web::GetWebFrameWithId(_webState, base::SysNSStringToUTF8(frameID)); web::GetWebFrameWithId(_webState, base::SysNSStringToUTF8(frameID));
[_JSAutofillManager clearAutofilledFieldsForFormName:formName [_JSAutofillManager
clearAutofilledFieldsForFormName:formName
formUniqueID:_lastFormActivityUniqueFormID
fieldIdentifier:fieldIdentifier fieldIdentifier:fieldIdentifier
fieldUniqueID:_lastFormActivityUniqueFieldID
inFrame:frame inFrame:frame
completionHandler:^(NSString*) { completionHandler:^(NSString*) {
if (completionHandler) { if (completionHandler) {
......
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