Skip to content

Commit

Permalink
[iOS] Create AutofillJavaScriptFeature
Browse files Browse the repository at this point in the history
AutofillJavaScriptFeature will migrate the closely related base
scripts used by autofill to a single JavaScriptFeature instance.

Initially, in this CL, only autofill_controller.js is migrated.

Also,to keep the CLs reasonably sized, the feature is remaining in the
page content worldL. Once all autofill scripts are migrated to
JavaScriptFeatures, the features will be moved to an isolated world.

The intended design of the migration process from raw JavaScript files
to JavaScriptFeature instances is at go/bling-autofill-jsfeatures.

Bug: 1175793
Change-Id: I0ed0c24ea2d3e604e015e6fa06655ef8021112cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2782072
Auto-Submit: Mike Dougherty <michaeldo@chromium.org>
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: John Wu <jzw@chromium.org>
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Reviewed-by: Moe Ahmadi <mahmadi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#867993}
  • Loading branch information
michaeldo1 authored and Chromium LUCI CQ committed Mar 31, 2021
1 parent eb74bd7 commit 612a4cc
Show file tree
Hide file tree
Showing 28 changed files with 555 additions and 627 deletions.
12 changes: 8 additions & 4 deletions components/autofill/ios/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ source_set("browser") {
"autofill_driver_ios_bridge.h",
"autofill_driver_ios_webframe.h",
"autofill_driver_ios_webframe.mm",
"autofill_java_script_feature.h",
"autofill_java_script_feature.mm",
"autofill_switches.cc",
"autofill_switches.h",
"autofill_util.h",
Expand All @@ -26,15 +28,14 @@ source_set("browser") {
"form_suggestion_provider.h",
"form_suggestion_provider_query.h",
"form_suggestion_provider_query.mm",
"js_autofill_manager.h",
"js_autofill_manager.mm",
"js_suggestion_manager.h",
"js_suggestion_manager.mm",
"personal_data_manager_observer_bridge.h",
"personal_data_manager_observer_bridge.mm",
]

deps = [
":autofill_js",
"//base",
"//components/autofill/core/browser",
"//components/autofill/core/common",
Expand All @@ -56,6 +57,11 @@ source_set("browser") {
]
}

js_compile_bundle("autofill_js") {
closure_entry_point = "__crWeb.autofill"
sources = [ "resources/autofill_controller.js" ]
}

source_set("test_support") {
testonly = true
configs += [ "//build/config/compiler:enable_arc" ]
Expand All @@ -64,8 +70,6 @@ source_set("test_support") {
"credit_card_save_manager_test_observer_bridge.mm",
"fake_autofill_agent.h",
"fake_autofill_agent.mm",
"fake_js_autofill_manager.h",
"fake_js_autofill_manager.mm",
"ios_test_event_waiter.h",
]
public_deps = [ ":browser" ]
Expand Down
128 changes: 63 additions & 65 deletions components/autofill/ios/browser/autofill_agent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_tick_clock.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/field_data_manager.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_data_predictions.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/ios/browser/autofill_driver_ios.h"
#include "components/autofill/ios/browser/autofill_driver_ios_webframe.h"
#import "components/autofill/ios/browser/autofill_java_script_feature.h"
#include "components/autofill/ios/browser/autofill_util.h"
#import "components/autofill/ios/browser/form_suggestion.h"
#import "components/autofill/ios/browser/form_suggestion_provider.h"
#import "components/autofill/ios/browser/js_autofill_manager.h"
#import "components/autofill/ios/form_util/form_activity_observer_bridge.h"
#include "components/autofill/ios/form_util/form_activity_params.h"
#include "components/autofill/ios/form_util/unique_id_data_tab_helper.h"
Expand Down Expand Up @@ -122,9 +123,6 @@ @interface AutofillAgent () <CRWWebStateObserver,
// The pref service for which this agent was created.
PrefService* _prefService;

// Manager for Autofill JavaScripts.
JsAutofillManager* _jsAutofillManager;

// The name and the unique renderer ID of the most recent autocomplete field;
// tracks the currently-focused form element in order to force filling of
// the currently selected form element, even if it's non-empty.
Expand Down Expand Up @@ -205,8 +203,6 @@ - (instancetype)initWithPrefService:(PrefService*)prefService
_prefObserverBridge->ObserveChangesForPreference(
autofill::prefs::kAutofillProfileEnabled, &_prefChangeRegistrar);

_jsAutofillManager = [[JsAutofillManager alloc] init];

UniqueIDDataTabHelper* uniqueIDDataTabHelper =
UniqueIDDataTabHelper::FromWebState(_webState);
_fieldDataManager = uniqueIDDataTabHelper->GetFieldDataManager();
Expand Down Expand Up @@ -280,16 +276,13 @@ - (void)fetchFormsFiltered:(BOOL)filtered
std::u16string formNameCopy = formName;
GURL pageURL = _webState->GetLastCommittedURL();
GURL frameOrigin = frame ? frame->GetSecurityOrigin() : pageURL.GetOrigin();
[_jsAutofillManager
fetchFormsWithMinimumRequiredFieldsCount:requiredFieldsCount
inFrame:frame
completionHandler:^(NSString* formJSON) {
std::vector<autofill::FormData> formData;
bool success = autofill::ExtractFormsData(
formJSON, filtered, formNameCopy, pageURL,
frameOrigin, &formData);
completionHandler(success, formData);
}];
autofill::AutofillJavaScriptFeature::GetInstance()->FetchForms(
frame, requiredFieldsCount, base::BindOnce(^(NSString* formJSON) {
std::vector<autofill::FormData> formData;
bool success = autofill::ExtractFormsData(
formJSON, filtered, formNameCopy, pageURL, frameOrigin, &formData);
completionHandler(success, formData);
}));
}

- (void)onSuggestionsReady:(NSArray<FormSuggestion*>*)suggestions
Expand Down Expand Up @@ -444,20 +437,16 @@ - (void)didSelectSuggestion:(FormSuggestion*)suggestion
SuggestionHandledCompletion suggestionHandledCompletionCopy =
[_suggestionHandledCompletion copy];
_suggestionHandledCompletion = nil;
[_jsAutofillManager
clearAutofilledFieldsForFormName:formName
formUniqueID:uniqueFormID
fieldIdentifier:fieldIdentifier
fieldUniqueID:uniqueFieldID
inFrame:frame
completionHandler:^(NSString* jsonString) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
[strongSelf
updateFieldManagerForClearedIDs:jsonString];
suggestionHandledCompletionCopy();
}];
autofill::AutofillJavaScriptFeature::GetInstance()
->ClearAutofilledFieldsForFormName(
frame, formName, uniqueFormID, fieldIdentifier, uniqueFieldID,
base::BindOnce(^(NSString* jsonString) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
[strongSelf updateFieldManagerForClearedIDs:jsonString];
suggestionHandledCompletionCopy();
}));

} else if (suggestion.identifier ==
autofill::POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS) {
Expand Down Expand Up @@ -517,7 +506,8 @@ - (void)fillFormData:(const autofill::FormData&)form
autofill::AutofillManager* autofillManager =
[self autofillManagerFromWebState:_webState webFrame:frame];
if (autofillManager)
autofillManager->OnDidFillAutofillFormData(form, base::TimeTicks::Now());
autofillManager->OnDidFillAutofillFormData(
form, autofill::AutofillTickClock::NowTicks());
}

- (void)handleParsedForms:(const std::vector<autofill::FormStructure*>&)forms
Expand Down Expand Up @@ -545,8 +535,8 @@ - (void)fillFormDataPredictions:
predictionData->SetKey(base::UTF16ToUTF8(form.data.name),
std::move(fieldData));
}
[_jsAutofillManager fillPredictionData:std::move(predictionData)
inFrame:frame];
autofill::AutofillJavaScriptFeature::GetInstance()->FillPredictionData(
frame, std::move(predictionData));
}

#pragma mark - AutofillClientIOSBridge
Expand Down Expand Up @@ -710,7 +700,9 @@ - (void)processFrame:(web::WebFrame*)frame inWebState:(web::WebState*)webState {
if (driver->is_processed())
return;
driver->set_processed(true);
[_jsAutofillManager addJSDelayInFrame:frame];
autofill::AutofillJavaScriptFeature* autofill_feature =
autofill::AutofillJavaScriptFeature::GetInstance();
autofill_feature->AddJSDelayInFrame(frame);

if (frame->IsMainFrame()) {
_popupDelegate.reset();
Expand All @@ -720,9 +712,19 @@ - (void)processFrame:(web::WebFrame*)frame inWebState:(web::WebState*)webState {
_typedValue = nil;
}

[_jsAutofillManager toggleTrackingFormMutations:YES inFrame:frame];
std::vector<base::Value> formMutationsParameters;
// Use a delay of 200ms when tracking form mutations to reduce the
// communication overhead (as mutations are likely to come in batch).
constexpr int kMutationTrackingEnabledDelayInMs = 200;
formMutationsParameters.push_back(
base::Value(kMutationTrackingEnabledDelayInMs));
frame->CallJavaScriptFunction("formHandlers.trackFormMutations",
formMutationsParameters);

[_jsAutofillManager toggleTrackingUserEditedFields:true inFrame:frame];
std::vector<base::Value> trackUserEditedFieldsParameters;
trackUserEditedFieldsParameters.push_back(base::Value(true));
frame->CallJavaScriptFunction("formHandlers.toggleTrackingUserEditedFields",
trackUserEditedFieldsParameters);

[self scanFormsInWebState:webState inFrame:frame];
}
Expand Down Expand Up @@ -805,8 +807,8 @@ - (void)webState:(web::WebState*)webState

autofill::FormFieldData field;
GetFormField(&field, forms[0], base::UTF8ToUTF16(fieldIdentifier));
autofillManager->OnTextFieldDidChange(forms[0], field, gfx::RectF(),
base::TimeTicks::Now());
autofillManager->OnTextFieldDidChange(
forms[0], field, gfx::RectF(), autofill::AutofillTickClock::NowTicks());
};

// Extract the active form and field only. There is no minimum field
Expand Down Expand Up @@ -903,19 +905,17 @@ - (void)fillField:(const std::string&)fieldIdentifier
SuggestionHandledCompletion suggestionHandledCompletionCopy =
[_suggestionHandledCompletion copy];
_suggestionHandledCompletion = nil;
[_jsAutofillManager
fillActiveFormField:std::move(data)
inFrame:frame
completionHandler:^(BOOL success) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
if (success) {
strongSelf->_fieldDataManager->UpdateFieldDataMap(
uniqueFieldID, value, kAutofilledOnUserTrigger);
}
suggestionHandledCompletionCopy();
}];
autofill::AutofillJavaScriptFeature::GetInstance()->FillActiveFormField(
frame, std::move(data), base::BindOnce(^(BOOL success) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
if (success) {
strongSelf->_fieldDataManager->UpdateFieldDataMap(
uniqueFieldID, value, kAutofilledOnUserTrigger);
}
suggestionHandledCompletionCopy();
}));
}

- (void)updateFieldManagerWithFillingResults:(NSString*)jsonString {
Expand Down Expand Up @@ -944,20 +944,18 @@ - (void)sendData:(std::unique_ptr<base::Value>)data
SuggestionHandledCompletion suggestionHandledCompletionCopy =
[_suggestionHandledCompletion copy];
_suggestionHandledCompletion = nil;
[_jsAutofillManager fillForm:std::move(data)
forceFillFieldIdentifier:SysUTF16ToNSString(_pendingAutocompleteField)
forceFillFieldUniqueID:_pendingAutocompleteFieldID
inFrame:frame
completionHandler:^(NSString* jsonString) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
[strongSelf updateFieldManagerWithFillingResults:jsonString];
// It is possible that the fill was not initiated by selecting
// a suggestion in this case the callback is nil.
if (suggestionHandledCompletionCopy)
suggestionHandledCompletionCopy();
}];
autofill::AutofillJavaScriptFeature::GetInstance()->FillForm(
frame, std::move(data), SysUTF16ToNSString(_pendingAutocompleteField),
_pendingAutocompleteFieldID, base::BindOnce(^(NSString* jsonString) {
AutofillAgent* strongSelf = weakSelf;
if (!strongSelf)
return;
[strongSelf updateFieldManagerWithFillingResults:jsonString];
// It is possible that the fill was not initiated by selecting
// a suggestion in this case the callback is nil.
if (suggestionHandledCompletionCopy)
suggestionHandledCompletionCopy();
}));
}

@end

0 comments on commit 612a4cc

Please sign in to comment.