Commit dbd360b3 authored by Javier Ernesto Flores Robles's avatar Javier Ernesto Flores Robles Committed by Commit Bot

[iOS][MF] Animate suggestions out and in

In order to add the animations some refactoring was required.
This also updates the suggestions view and form accessory view instead
of recreating them every time new suggestions arrive.
Continues the UI layering of these views, by removing the navigator
related logic from them.
Relies on setting content insets instead of removing suggestions to
lock on the manual fill icons.
Refactors names of delegates and properties to more appropriate ones
Fixes an issue when disabled suggestions was ignored when jumping
between fields.



Bug: 905651, 907084, 845472, 905660
Change-Id: I4ceebcabadbb26e6d948c26f9691d5684a143b79
Reviewed-on: https://chromium-review.googlesource.com/c/1346833
Commit-Queue: Javier Ernesto Flores Robles <javierrobles@chromium.org>
Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610611}
parent ffbda136
...@@ -77,9 +77,9 @@ source_set("autofill") { ...@@ -77,9 +77,9 @@ source_set("autofill") {
source_set("autofill_shared") { source_set("autofill_shared") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
sources = [ sources = [
"form_input_accessory_view_delegate.h",
"form_input_accessory_view_handler.h", "form_input_accessory_view_handler.h",
"form_input_accessory_view_handler.mm", "form_input_accessory_view_handler.mm",
"form_input_navigator.h",
"form_input_suggestions_provider.h", "form_input_suggestions_provider.h",
"form_suggestion_client.h", "form_suggestion_client.h",
] ]
......
...@@ -13,6 +13,16 @@ ...@@ -13,6 +13,16 @@
@protocol FormInputAccessoryConsumer<NSObject> @protocol FormInputAccessoryConsumer<NSObject>
// Delegate used for form navigation.
@property(nonatomic, weak) id<FormInputAccessoryViewDelegate>
navigationDelegate;
// Enables or disables the next button if any.
@property(nonatomic) BOOL formInputNextButtonEnabled;
// Enables or disables the previous button if any.
@property(nonatomic) BOOL formInputPreviousButtonEnabled;
// Removes the animations on the custom keyboard view. // Removes the animations on the custom keyboard view.
- (void)removeAnimationsOnKeyboardView; - (void)removeAnimationsOnKeyboardView;
...@@ -33,8 +43,6 @@ ...@@ -33,8 +43,6 @@
// |isHardwareKeyboard| is true if a hardware keyboard is in use. // |isHardwareKeyboard| is true if a hardware keyboard is in use.
- (void)showAccessorySuggestions:(NSArray<FormSuggestion*>*)suggestions - (void)showAccessorySuggestions:(NSArray<FormSuggestion*>*)suggestions
suggestionClient:(id<FormSuggestionClient>)suggestionClient suggestionClient:(id<FormSuggestionClient>)suggestionClient
navigationDelegate:
(id<FormInputAccessoryViewDelegate>)navigationDelegate
isHardwareKeyboard:(BOOL)hardwareKeyboard; isHardwareKeyboard:(BOOL)hardwareKeyboard;
@end @end
......
...@@ -7,13 +7,32 @@ ...@@ -7,13 +7,32 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@protocol FormInputAccessoryViewDelegate; @class FormInputAccessoryView;
// Informs the receiver of actions in the accessory view.
@protocol FormInputAccessoryViewDelegate
- (void)formInputAccessoryViewDidTapNextButton:(FormInputAccessoryView*)sender;
- (void)formInputAccessoryViewDidTapPreviousButton:
(FormInputAccessoryView*)sender;
- (void)formInputAccessoryViewDidTapCloseButton:(FormInputAccessoryView*)sender;
@end
// Subview of the accessory view for web forms. Shows a custom view with form // Subview of the accessory view for web forms. Shows a custom view with form
// navigation controls above the keyboard. Enables input clicks by way of the // navigation controls above the keyboard. Enables input clicks by way of the
// playInputClick method. // playInputClick method.
@interface FormInputAccessoryView : UIView<UIInputViewAudioFeedback> @interface FormInputAccessoryView : UIView<UIInputViewAudioFeedback>
// The previous button if the view was set up with a navigation delegate. Nil
// otherwise.
@property(nonatomic, readonly, weak) UIButton* previousButton;
// The next button if the view was set up with a navigation delegate. Nil
// otherwise.
@property(nonatomic, readonly, weak) UIButton* nextButton;
// The leading view.
@property(nonatomic, readonly, weak) UIView* leadingView;
// Sets up the view with the given |leadingView|. Navigation controls are shown // Sets up the view with the given |leadingView|. Navigation controls are shown
// on the trailing side and use |delegate| for actions. // on the trailing side and use |delegate| for actions.
- (void)setUpWithLeadingView:(UIView*)leadingView - (void)setUpWithLeadingView:(UIView*)leadingView
......
...@@ -29,6 +29,14 @@ extern CGFloat const kInputAccessoryHeight; ...@@ -29,6 +29,14 @@ extern CGFloat const kInputAccessoryHeight;
// Presents a view above the keyboard. // Presents a view above the keyboard.
- (void)presentView:(UIView*)view; - (void)presentView:(UIView*)view;
// Frees the manual fallback icons as the first option in the suggestions bar,
// and animates any suggestion back to their original position.
- (void)unlockManualFallbackView;
// Shows the manual fallback icons as the first option in the suggestions bar,
// and locks them in that position.
- (void)lockManualFallbackView;
@end @end
#endif // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_CONTROLLER_H_ #endif // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_CONTROLLER_H_
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
#ifndef IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_ #ifndef IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_
#define IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_ #define IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_
#import "ios/chrome/browser/autofill/form_input_accessory_view_delegate.h" #import "ios/chrome/browser/autofill/form_input_navigator.h"
@class JsSuggestionManager; @class JsSuggestionManager;
// This handles user actions in the default keyboard accessory view buttons. // This handles user actions in the default keyboard accessory view buttons.
@interface FormInputAccessoryViewHandler @interface FormInputAccessoryViewHandler : NSObject <FormInputNavigator>
: NSObject<FormInputAccessoryViewDelegate>
// The JS manager for interacting with the underlying form. // The JS manager for interacting with the underlying form.
@property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager; @property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager;
......
...@@ -182,7 +182,7 @@ NSArray* FindDescendantToolbarItemsForActionName( ...@@ -182,7 +182,7 @@ NSArray* FindDescendantToolbarItemsForActionName(
new autofill::KeyboardAccessoryMetricsLogger()); new autofill::KeyboardAccessoryMetricsLogger());
} }
#pragma mark - FormInputAccessoryViewDelegate #pragma mark - FormInputNavigator
- (void)closeKeyboardWithButtonPress { - (void)closeKeyboardWithButtonPress {
[self closeKeyboardLoggingButtonPressed:YES]; [self closeKeyboardLoggingButtonPressed:YES];
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_DELEGATE_H_ #ifndef IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_NAVIGATOR_H_
#define IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_DELEGATE_H_ #define IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_NAVIGATOR_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
// Handles user interaction with a FormInputAccessoryView. // Handles navigation in a form.
@protocol FormInputAccessoryViewDelegate<NSObject> @protocol FormInputNavigator <NSObject>
// Called when the close button is pressed by the user. // Called when the close button is pressed by the user.
- (void)closeKeyboardWithButtonPress; - (void)closeKeyboardWithButtonPress;
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
// previous element was found, and the second indicating if a next element was // previous element was found, and the second indicating if a next element was
// found. |completionHandler| cannot be nil. // found. |completionHandler| cannot be nil.
- (void)fetchPreviousAndNextElementsPresenceWithCompletionHandler: - (void)fetchPreviousAndNextElementsPresenceWithCompletionHandler:
(void (^)(BOOL, BOOL))completionHandler; (void (^)(BOOL, BOOL))completionHandler;
@end @end
#endif // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_DELEGATE_H_ #endif // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_NAVIGATOR_H_
...@@ -19,7 +19,7 @@ class WebState; ...@@ -19,7 +19,7 @@ class WebState;
} // namespace web } // namespace web
@class FormSuggestion; @class FormSuggestion;
@protocol FormInputAccessoryViewDelegate; @protocol FormInputNavigator;
@protocol FormInputSuggestionsProvider; @protocol FormInputSuggestionsProvider;
// Block type to provide form suggestions asynchronously. // Block type to provide form suggestions asynchronously.
...@@ -31,8 +31,7 @@ typedef void (^FormSuggestionsReadyCompletion)( ...@@ -31,8 +31,7 @@ typedef void (^FormSuggestionsReadyCompletion)(
@protocol FormInputSuggestionsProvider<FormSuggestionClient> @protocol FormInputSuggestionsProvider<FormSuggestionClient>
// A delegate for form navigation. // A delegate for form navigation.
@property(nonatomic, assign) id<FormInputAccessoryViewDelegate> @property(nonatomic, weak) id<FormInputNavigator> formInputNavigator;
accessoryViewDelegate;
// Asynchronously retrieves form suggestions from this provider for the // Asynchronously retrieves form suggestions from this provider for the
// specified form/field and returns it via |accessoryViewUpdateBlock|. View // specified form/field and returns it via |accessoryViewUpdateBlock|. View
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#import "components/autofill/ios/browser/form_suggestion_provider.h" #import "components/autofill/ios/browser/form_suggestion_provider.h"
#include "components/autofill/ios/form_util/form_activity_params.h" #include "components/autofill/ios/form_util/form_activity_params.h"
#import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h" #import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h"
#import "ios/chrome/browser/autofill/form_input_accessory_view_delegate.h" #import "ios/chrome/browser/autofill/form_input_navigator.h"
#import "ios/chrome/browser/autofill/form_input_suggestions_provider.h" #import "ios/chrome/browser/autofill/form_input_suggestions_provider.h"
#import "ios/chrome/browser/autofill/form_suggestion_view.h" #import "ios/chrome/browser/autofill/form_suggestion_view.h"
#import "ios/chrome/browser/passwords/password_generation_utils.h" #import "ios/chrome/browser/passwords/password_generation_utils.h"
...@@ -63,9 +63,6 @@ AutofillSuggestionState::AutofillSuggestionState( ...@@ -63,9 +63,6 @@ AutofillSuggestionState::AutofillSuggestionState(
} // namespace } // namespace
@interface FormSuggestionController ()<FormInputSuggestionsProvider> { @interface FormSuggestionController ()<FormInputSuggestionsProvider> {
// Form navigation delegate.
__weak id<FormInputAccessoryViewDelegate> _delegate;
// Callback to update the accessory view. // Callback to update the accessory view.
FormSuggestionsReadyCompletion accessoryViewUpdateBlock_; FormSuggestionsReadyCompletion accessoryViewUpdateBlock_;
...@@ -106,6 +103,8 @@ AutofillSuggestionState::AutofillSuggestionState( ...@@ -106,6 +103,8 @@ AutofillSuggestionState::AutofillSuggestionState(
__weak id<FormSuggestionProvider> _provider; __weak id<FormSuggestionProvider> _provider;
} }
@synthesize formInputNavigator = _formInputNavigator;
- (instancetype)initWithWebState:(web::WebState*)webState - (instancetype)initWithWebState:(web::WebState*)webState
providers:(NSArray*)providers providers:(NSArray*)providers
JsSuggestionManager:(JsSuggestionManager*)jsSuggestionManager { JsSuggestionManager:(JsSuggestionManager*)jsSuggestionManager {
...@@ -319,20 +318,12 @@ AutofillSuggestionState::AutofillSuggestionState( ...@@ -319,20 +318,12 @@ AutofillSuggestionState::AutofillSuggestionState(
frameID:base::SysUTF8ToNSString( frameID:base::SysUTF8ToNSString(
_suggestionState->frame_identifier) _suggestionState->frame_identifier)
completionHandler:^{ completionHandler:^{
[[weakSelf accessoryViewDelegate] closeKeyboardWithoutButtonPress]; [[weakSelf formInputNavigator] closeKeyboardWithoutButtonPress];
}]; }];
} }
#pragma mark FormInputSuggestionsProvider #pragma mark FormInputSuggestionsProvider
- (id<FormInputAccessoryViewDelegate>)accessoryViewDelegate {
return _delegate;
}
- (void)setAccessoryViewDelegate:(id<FormInputAccessoryViewDelegate>)delegate {
_delegate = delegate;
}
- (void)retrieveSuggestionsForForm:(const autofill::FormActivityParams&)params - (void)retrieveSuggestionsForForm:(const autofill::FormActivityParams&)params
webState:(web::WebState*)webState webState:(web::WebState*)webState
accessoryViewUpdateBlock: accessoryViewUpdateBlock:
......
...@@ -186,7 +186,6 @@ class FormSuggestionControllerTest : public PlatformTest { ...@@ -186,7 +186,6 @@ class FormSuggestionControllerTest : public PlatformTest {
[[[mock_consumer_ stub] andDo:mockShow] [[[mock_consumer_ stub] andDo:mockShow]
showAccessorySuggestions:[OCMArg any] showAccessorySuggestions:[OCMArg any]
suggestionClient:[OCMArg any] suggestionClient:[OCMArg any]
navigationDelegate:[OCMArg any]
isHardwareKeyboard:NO]; isHardwareKeyboard:NO];
// Mock restore keyboard to verify cleanup. // Mock restore keyboard to verify cleanup.
......
...@@ -19,10 +19,16 @@ ...@@ -19,10 +19,16 @@
// A view added at the end of the current suggestions. // A view added at the end of the current suggestions.
@property(nonatomic, strong) UIView* trailingView; @property(nonatomic, strong) UIView* trailingView;
// Initializes with |frame| and |client| to show |suggestions|. // Updates with |client| and |suggestions|.
- (instancetype)initWithFrame:(CGRect)frame - (void)updateClient:(id<FormSuggestionClient>)client
client:(id<FormSuggestionClient>)client suggestions:(NSArray<FormSuggestion*>*)suggestions;
suggestions:(NSArray<FormSuggestion*>*)suggestions;
// Animates the content insets back to zero.
- (void)unlockTrailingView;
// Animates the content insets so the trailing view is showed as the first
// thing.
- (void)lockTrailingView;
@end @end
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#import "components/autofill/ios/browser/form_suggestion.h" #import "components/autofill/ios/browser/form_suggestion.h"
#import "ios/chrome/browser/autofill/form_suggestion_client.h" #import "ios/chrome/browser/autofill/form_suggestion_client.h"
#import "ios/chrome/browser/autofill/form_suggestion_label.h" #import "ios/chrome/browser/autofill/form_suggestion_label.h"
#include "ios/chrome/browser/ui/util/rtl_geometry.h"
#include "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/common/ui_util/constraints_ui_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -30,33 +31,64 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -30,33 +31,64 @@ const CGFloat kSuggestionHorizontalMargin = 6;
@interface FormSuggestionView () @interface FormSuggestionView ()
// Creates and adds subviews. // The FormSuggestions that are displayed by this view.
- (void)setupSubviews; @property(nonatomic) NSArray<FormSuggestion*>* suggestions;
// The stack view with the suggestions.
@property(nonatomic) UIStackView* stackView;
// Handles user interactions.
@property(nonatomic, weak) id<FormSuggestionClient> client;
@end @end
@implementation FormSuggestionView { @implementation FormSuggestionView
// The FormSuggestions that are displayed by this view.
NSArray* _suggestions; #pragma mark - Public
// The stack view with the suggestions. - (void)updateClient:(id<FormSuggestionClient>)client
UIStackView* _stackView; suggestions:(NSArray<FormSuggestion*>*)suggestions {
if ([self.suggestions isEqualToArray:suggestions] &&
(self.client == client || !suggestions.count)) {
return;
}
self.client = client;
self.suggestions = [suggestions copy];
// Handles user interactions. if (self.stackView) {
id<FormSuggestionClient> _client; for (UIView* view in [self.stackView.arrangedSubviews copy]) {
[self.stackView removeArrangedSubview:view];
[view removeFromSuperview];
}
self.contentInset = UIEdgeInsetsZero;
[self createAndInsertArrangedSubviews];
}
} }
@synthesize trailingView = _trailingView; - (void)unlockTrailingView {
if (!self.superview) {
return;
}
[UIView animateWithDuration:0.2
animations:^{
self.contentInset = UIEdgeInsetsZero;
}];
}
- (instancetype)initWithFrame:(CGRect)frame - (void)lockTrailingView {
client:(id<FormSuggestionClient>)client if (!self.superview || !self.trailingView) {
suggestions:(NSArray<FormSuggestion*>*)suggestions { return;
self = [super initWithFrame:frame];
if (self) {
_client = client;
_suggestions = [suggestions copy];
} }
return self;
LayoutOffset layoutOffset = CGRectGetLeadingLayoutOffsetInBoundingRect(
self.trailingView.frame, {CGPointZero, self.contentSize});
// Because the way the scroll view is transformed for RTL, the insets don't
// need to be directed.
UIEdgeInsets lockedContentInsets = UIEdgeInsetsMake(0, -layoutOffset, 0, 0);
[UIView animateWithDuration:0.2
animations:^{
self.contentInset = lockedContentInsets;
}];
} }
#pragma mark - UIView #pragma mark - UIView
...@@ -71,10 +103,12 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -71,10 +103,12 @@ const CGFloat kSuggestionHorizontalMargin = 6;
#pragma mark - Helper methods #pragma mark - Helper methods
// Creates and adds subviews.
- (void)setupSubviews { - (void)setupSubviews {
self.showsVerticalScrollIndicator = NO; self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO; self.showsHorizontalScrollIndicator = NO;
self.canCancelContentTouches = YES; self.canCancelContentTouches = YES;
self.alwaysBounceHorizontal = YES;
UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:@[]]; UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:@[]];
stackView.axis = UILayoutConstraintAxisHorizontal; stackView.axis = UILayoutConstraintAxisHorizontal;
...@@ -95,7 +129,11 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -95,7 +129,11 @@ const CGFloat kSuggestionHorizontalMargin = 6;
self.transform = CGAffineTransformMakeRotation(M_PI); self.transform = CGAffineTransformMakeRotation(M_PI);
stackView.transform = CGAffineTransformMakeRotation(M_PI); stackView.transform = CGAffineTransformMakeRotation(M_PI);
} }
self.stackView = stackView;
[self createAndInsertArrangedSubviews];
}
- (void)createAndInsertArrangedSubviews {
auto setupBlock = ^(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) { auto setupBlock = ^(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) {
// Disable user interaction with suggestion if it is Google Pay logo. // Disable user interaction with suggestion if it is Google Pay logo.
BOOL userInteractionEnabled = BOOL userInteractionEnabled =
...@@ -105,9 +143,9 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -105,9 +143,9 @@ const CGFloat kSuggestionHorizontalMargin = 6;
[[FormSuggestionLabel alloc] initWithSuggestion:suggestion [[FormSuggestionLabel alloc] initWithSuggestion:suggestion
index:idx index:idx
userInteractionEnabled:userInteractionEnabled userInteractionEnabled:userInteractionEnabled
numSuggestions:[_suggestions count] numSuggestions:[self.suggestions count]
client:_client]; client:self.client];
[stackView addArrangedSubview:label]; [self.stackView addArrangedSubview:label];
// If first suggestion is Google Pay logo animate it below the fold. // If first suggestion is Google Pay logo animate it below the fold.
if (idx == 0U && if (idx == 0U &&
...@@ -126,17 +164,10 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -126,17 +164,10 @@ const CGFloat kSuggestionHorizontalMargin = 6;
}); });
} }
}; };
[_suggestions enumerateObjectsUsingBlock:setupBlock]; [self.suggestions enumerateObjectsUsingBlock:setupBlock];
if (self.trailingView) { if (self.trailingView) {
[stackView addArrangedSubview:self.trailingView]; [self.stackView addArrangedSubview:self.trailingView];
} }
_stackView = stackView;
}
#pragma mark - Getters
- (NSArray*)suggestions {
return _suggestions;
} }
#pragma mark - Setters #pragma mark - Setters
...@@ -144,6 +175,7 @@ const CGFloat kSuggestionHorizontalMargin = 6; ...@@ -144,6 +175,7 @@ const CGFloat kSuggestionHorizontalMargin = 6;
- (void)setTrailingView:(UIView*)subview { - (void)setTrailingView:(UIView*)subview {
if (_trailingView.superview) { if (_trailingView.superview) {
[_stackView removeArrangedSubview:_trailingView]; [_stackView removeArrangedSubview:_trailingView];
[_trailingView removeFromSuperview];
} }
_trailingView = subview; _trailingView = subview;
if (_stackView) { if (_stackView) {
......
...@@ -177,7 +177,6 @@ ...@@ -177,7 +177,6 @@
} }
[self.childCoordinators addObject:passwordCoordinator]; [self.childCoordinators addObject:passwordCoordinator];
[self.formInputAccessoryMediator disableSuggestions];
} }
- (void)startCardsFromButton:(UIButton*)button { - (void)startCardsFromButton:(UIButton*)button {
...@@ -195,7 +194,6 @@ ...@@ -195,7 +194,6 @@
} }
[self.childCoordinators addObject:cardCoordinator]; [self.childCoordinators addObject:cardCoordinator];
[self.formInputAccessoryMediator disableSuggestions];
} }
- (void)startAddressFromButton:(UIButton*)button { - (void)startAddressFromButton:(UIButton*)button {
...@@ -212,7 +210,6 @@ ...@@ -212,7 +210,6 @@
} }
[self.childCoordinators addObject:addressCoordinator]; [self.childCoordinators addObject:addressCoordinator];
[self.formInputAccessoryMediator disableSuggestions];
} }
#pragma mark - ManualFillAccessoryViewControllerDelegate #pragma mark - ManualFillAccessoryViewControllerDelegate
...@@ -220,21 +217,28 @@ ...@@ -220,21 +217,28 @@
- (void)keyboardButtonPressed { - (void)keyboardButtonPressed {
[self stopChildren]; [self stopChildren];
[self.formInputAccessoryMediator enableSuggestions]; [self.formInputAccessoryMediator enableSuggestions];
[self.formInputAccessoryViewController unlockManualFallbackView];
} }
- (void)accountButtonPressed:(UIButton*)sender { - (void)accountButtonPressed:(UIButton*)sender {
[self stopChildren]; [self stopChildren];
[self startAddressFromButton:sender]; [self startAddressFromButton:sender];
[self.formInputAccessoryViewController lockManualFallbackView];
[self.formInputAccessoryMediator disableSuggestions];
} }
- (void)cardButtonPressed:(UIButton*)sender { - (void)cardButtonPressed:(UIButton*)sender {
[self stopChildren]; [self stopChildren];
[self startCardsFromButton:sender]; [self startCardsFromButton:sender];
[self.formInputAccessoryViewController lockManualFallbackView];
[self.formInputAccessoryMediator disableSuggestions];
} }
- (void)passwordButtonPressed:(UIButton*)sender { - (void)passwordButtonPressed:(UIButton*)sender {
[self stopChildren]; [self stopChildren];
[self startPasswordsFromButton:sender]; [self startPasswordsFromButton:sender];
[self.formInputAccessoryViewController lockManualFallbackView];
[self.formInputAccessoryMediator disableSuggestions];
} }
#pragma mark - PasswordCoordinatorDelegate #pragma mark - PasswordCoordinatorDelegate
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "ios/chrome/browser/autofill/form_input_accessory_view_delegate.h" #import "ios/chrome/browser/autofill/form_input_navigator.h"
#import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
#import "ios/web/public/web_state/web_state_observer_bridge.h" #import "ios/web/public/web_state/web_state_observer_bridge.h"
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#import "components/autofill/ios/form_util/form_activity_observer_bridge.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/form_activity_params.h"
#import "ios/chrome/browser/autofill/form_input_accessory_consumer.h" #import "ios/chrome/browser/autofill/form_input_accessory_consumer.h"
#import "ios/chrome/browser/autofill/form_input_accessory_view.h"
#import "ios/chrome/browser/autofill/form_input_accessory_view_handler.h" #import "ios/chrome/browser/autofill/form_input_accessory_view_handler.h"
#import "ios/chrome/browser/autofill/form_input_suggestions_provider.h" #import "ios/chrome/browser/autofill/form_input_suggestions_provider.h"
#import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h" #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
...@@ -33,10 +34,11 @@ ...@@ -33,10 +34,11 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
@interface FormInputAccessoryMediator ()<FormActivityObserver, @interface FormInputAccessoryMediator () <FormActivityObserver,
CRWWebStateObserver, FormInputAccessoryViewDelegate,
KeyboardObserverHelperDelegate, CRWWebStateObserver,
WebStateListObserving> KeyboardObserverHelperDelegate,
WebStateListObserving>
// The JS manager for interacting with the underlying form. // The JS manager for interacting with the underlying form.
@property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager; @property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager;
...@@ -100,6 +102,7 @@ ...@@ -100,6 +102,7 @@
self = [super init]; self = [super init];
if (self) { if (self) {
_consumer = consumer; _consumer = consumer;
_consumer.navigationDelegate = self;
if (webStateList) { if (webStateList) {
_webStateList = webStateList; _webStateList = webStateList;
_webStateListObserver = _webStateListObserver =
...@@ -209,12 +212,29 @@ ...@@ -209,12 +212,29 @@
return; return;
} }
[_formInputAccessoryHandler [self.formInputAccessoryHandler
setLastFocusFormActivityWebFrameID:base::SysUTF8ToNSString( setLastFocusFormActivityWebFrameID:base::SysUTF8ToNSString(
params.frame_id)]; params.frame_id)];
[self synchronizeNavigationControls];
[self retrieveSuggestionsForForm:params webState:webState]; [self retrieveSuggestionsForForm:params webState:webState];
} }
#pragma mark - FormInputAccessoryViewDelegate
- (void)formInputAccessoryViewDidTapNextButton:(FormInputAccessoryView*)sender {
[self.formInputAccessoryHandler selectNextElementWithButtonPress];
}
- (void)formInputAccessoryViewDidTapPreviousButton:
(FormInputAccessoryView*)sender {
[self.formInputAccessoryHandler selectPreviousElementWithButtonPress];
}
- (void)formInputAccessoryViewDidTapCloseButton:
(FormInputAccessoryView*)sender {
[self.formInputAccessoryHandler closeKeyboardWithButtonPress];
}
#pragma mark - CRWWebStateObserver #pragma mark - CRWWebStateObserver
- (void)webStateWasShown:(web::WebState*)webState { - (void)webStateWasShown:(web::WebState*)webState {
...@@ -263,7 +283,6 @@ ...@@ -263,7 +283,6 @@
- (void)disableSuggestions { - (void)disableSuggestions {
self.suggestionsDisabled = YES; self.suggestionsDisabled = YES;
[self updateWithProvider:nil suggestions:nil];
} }
- (void)enableSuggestions { - (void)enableSuggestions {
...@@ -282,11 +301,24 @@ ...@@ -282,11 +301,24 @@
} }
[_currentProvider inputAccessoryViewControllerDidReset]; [_currentProvider inputAccessoryViewControllerDidReset];
_currentProvider = currentProvider; _currentProvider = currentProvider;
[_currentProvider setAccessoryViewDelegate:self.formInputAccessoryHandler]; _currentProvider.formInputNavigator = self.formInputAccessoryHandler;
} }
#pragma mark - Private #pragma mark - Private
// Update the status of the consumer form navigation buttons to match the
// handler state.
- (void)synchronizeNavigationControls {
__weak __typeof(self) weakSelf = self;
[self.formInputAccessoryHandler
fetchPreviousAndNextElementsPresenceWithCompletionHandler:^(
BOOL previousButtonEnabled, BOOL nextButtonEnabled) {
weakSelf.consumer.formInputNextButtonEnabled = nextButtonEnabled;
weakSelf.consumer.formInputPreviousButtonEnabled =
previousButtonEnabled;
}];
}
// Updates the accessory mediator with the passed web state, its JS suggestion // Updates the accessory mediator with the passed web state, its JS suggestion
// manager and the registered providers. If NULL is passed it will instead clear // manager and the registered providers. If NULL is passed it will instead clear
// those properties in the mediator. // those properties in the mediator.
...@@ -405,19 +437,15 @@ queryViewBlockForProvider:(id<FormInputSuggestionsProvider>)provider ...@@ -405,19 +437,15 @@ queryViewBlockForProvider:(id<FormInputSuggestionsProvider>)provider
// If the suggestions are disabled, post this view with no suggestions to the // If the suggestions are disabled, post this view with no suggestions to the
// consumer. This allows the navigation buttons be in sync. // consumer. This allows the navigation buttons be in sync.
if (self.suggestionsDisabled) { if (self.suggestionsDisabled) {
[self.consumer showAccessorySuggestions:@[] return;
suggestionClient:provider
navigationDelegate:self.formInputAccessoryHandler
isHardwareKeyboard:self.hardwareKeyboard];
} else { } else {
// If suggestions are enabled update |currentProvider|. // If suggestions are enabled update |currentProvider|.
self.currentProvider = provider; self.currentProvider = provider;
// Post it to the consumer.
[self.consumer showAccessorySuggestions:suggestions
suggestionClient:provider
isHardwareKeyboard:self.hardwareKeyboard];
} }
// Post it to the consumer.
[self.consumer showAccessorySuggestions:suggestions
suggestionClient:provider
navigationDelegate:self.formInputAccessoryHandler
isHardwareKeyboard:self.hardwareKeyboard];
} }
#pragma mark - Keyboard Notifications #pragma mark - Keyboard Notifications
......
...@@ -39,7 +39,7 @@ constexpr CGFloat ManualFillIconsRightInset = 24; ...@@ -39,7 +39,7 @@ constexpr CGFloat ManualFillIconsRightInset = 24;
} // namespace } // namespace
static NSTimeInterval MFAnimationDuration = 0; static NSTimeInterval MFAnimationDuration = 0.2;
@interface ManualFillAccessoryViewController () @interface ManualFillAccessoryViewController ()
......
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