Commit f111c544 authored by Alfonso Garza's avatar Alfonso Garza Committed by Commit Bot

Fix issue when deleting from a textfield.

Fix issue when deleting from a textfield and an emoji is present, where
the last character would get deleted. Also moves card holder name down
in the list of items as requested by UX.

The main issue, which also has other unintended side effects, is that
|reconfigureCellsForItems| is called while the text is being edited.
This causes the cell to be redrawn and the cursor to change.

By doing this call in TableViewTextEditItemDelegate as opposed to
before the text changes we resolve the issue of the last character
being deleted instead of the correct one. There is a smaller issue
that remains and is not trivial to fix: after deletion the cursor
is moved to the end of the text. This also exists in other
textfields.

Bug: 1114718
Change-Id: Id035e5b3c066801a3e156360f010380104564931
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2360514
Commit-Queue: Alfonso Garza <alfonsogarza@google.com>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800385}
parent a03c4a28
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_edit_table_view_controller+protected.h" #import "ios/chrome/browser/ui/settings/autofill/autofill_edit_table_view_controller+protected.h"
#import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h" #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item_delegate.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_chromium_strings.h"
...@@ -57,11 +58,8 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -57,11 +58,8 @@ typedef NS_ENUM(NSInteger, ItemType) {
} // namespace } // namespace
@interface AutofillCreditCardEditTableViewController () @interface AutofillCreditCardEditTableViewController () <
TableViewTextEditItemDelegate>
// The nickname cell. Need to keep reference to update validation style.
@property(nonatomic, strong) TableViewTextEditCell* nicknameCell;
@end @end
@implementation AutofillCreditCardEditTableViewController { @implementation AutofillCreditCardEditTableViewController {
...@@ -168,10 +166,10 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -168,10 +166,10 @@ typedef NS_ENUM(NSInteger, ItemType) {
NSArray<AutofillEditItem*>* editItems; NSArray<AutofillEditItem*>* editItems;
if ([self isCardNicknameManagementEnabled]) { if ([self isCardNicknameManagementEnabled]) {
editItems = @[ editItems = @[
[self cardholderNameItem:isEditing],
[self cardNumberItem:isEditing], [self cardNumberItem:isEditing],
[self expirationMonthItem:isEditing], [self expirationMonthItem:isEditing],
[self expirationYearItem:isEditing], [self expirationYearItem:isEditing],
[self cardholderNameItem:isEditing],
[self nicknameItem:isEditing], [self nicknameItem:isEditing],
]; ];
} else { } else {
...@@ -198,57 +196,42 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -198,57 +196,42 @@ typedef NS_ENUM(NSInteger, ItemType) {
} }
} }
#pragma mark - UITextFieldDelegate #pragma mark - TableViewTextEditItemDelegate
// This method is called as the text is being typed in, pasted, or deleted. Asks
// the delegate if the text should be changed. Should always return YES. During
// typing/pasting text, |newText| contains one or more new characters. When user
// deletes text, |newText| is empty. |range| is the range of characters to be
// replaced.
- (BOOL)textField:(UITextField*)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString*)newText {
// Find the respective item for the text field.
NSIndexPath* indexPath = [self indexPathForCurrentTextField];
DCHECK(indexPath);
AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>(
[self.tableViewModel itemAtIndexPath:indexPath]);
// If the user is typing in the credit card number field, update the card type
// icon (e.g. "Visa") to reflect the number being typed.
if (item.autofillUIType == AutofillUITypeCreditCardNumber) {
// Obtain the text being typed.
NSString* updatedText =
[textField.text stringByReplacingCharactersInRange:range
withString:newText];
const char* network = autofill::CreditCard::GetCardNetwork(
base::SysNSStringToUTF16(updatedText));
item.identifyingIcon = [self cardTypeIconFromNetwork:network];
// Update the cell.
[self reconfigureCellsForItems:@[ item ]];
}
NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; - (void)tableViewItemDidBeginEditing:
if (itemType == ItemTypeNickname) { (TableViewTextEditItem*)tableViewTextEditItem {
NSString* updatedText = // No op.
[textField.text stringByReplacingCharactersInRange:range }
withString:newText];
updatedText = [updatedText - (void)tableViewItemDidChange:(TableViewTextEditItem*)tableViewTextEditItem {
stringByTrimmingCharactersInSet:[NSCharacterSet if ([tableViewTextEditItem isKindOfClass:[AutofillEditItem class]]) {
whitespaceAndNewlineCharacterSet]]; AutofillEditItem* item = (AutofillEditItem*)tableViewTextEditItem;
BOOL validNickname = autofill::CreditCard::IsNicknameValid( // If the user is typing in the credit card number field, update the card
base::SysNSStringToUTF16(updatedText)); // type icon (e.g. "Visa") to reflect the number being typed.
[item setHasValidText:validNickname]; if (item.autofillUIType == AutofillUITypeCreditCardNumber) {
[self reconfigureCellsForItems:@[ item ]]; const char* network = autofill::CreditCard::GetCardNetwork(
TableViewTextEditItemIconType icon = base::SysNSStringToUTF16(item.textFieldValue));
validNickname ? TableViewTextEditItemIconTypeEdit item.identifyingIcon = [self cardTypeIconFromNetwork:network];
: TableViewTextEditItemIconTypeError; [self reconfigureCellsForItems:@[ item ]];
[self.nicknameCell setIcon:icon]; }
self.navigationItem.rightBarButtonItem.enabled = validNickname;
if (item.type == ItemTypeNickname) {
NSString* trimmedText = [item.textFieldValue
stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
BOOL newNicknameIsValid = autofill::CreditCard::IsNicknameValid(
base::SysNSStringToUTF16(trimmedText));
self.navigationItem.rightBarButtonItem.enabled = newNicknameIsValid;
[item setHasValidText:newNicknameIsValid];
[self reconfigureCellsForItems:@[ item ]];
}
} }
}
return YES; - (void)tableViewItemDidEndEditing:
(TableViewTextEditItem*)tableViewTextEditItem {
// No op.
} }
#pragma mark - UITableViewDataSource #pragma mark - UITableViewDataSource
...@@ -268,10 +251,7 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -268,10 +251,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
case ItemTypeCardNumber: case ItemTypeCardNumber:
case ItemTypeExpirationMonth: case ItemTypeExpirationMonth:
case ItemTypeExpirationYear: case ItemTypeExpirationYear:
break;
case ItemTypeNickname: case ItemTypeNickname:
self.nicknameCell =
base::mac::ObjCCastStrict<TableViewTextEditCell>(cell);
break; break;
case ItemTypeCopiedToChrome: { case ItemTypeCopiedToChrome: {
CopiedToChromeCell* copiedToChromeCell = CopiedToChromeCell* copiedToChromeCell =
...@@ -365,6 +345,7 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -365,6 +345,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
cardNumberItem.autofillUIType = AutofillUITypeCreditCardNumber; cardNumberItem.autofillUIType = AutofillUITypeCreditCardNumber;
cardNumberItem.keyboardType = UIKeyboardTypeNumberPad; cardNumberItem.keyboardType = UIKeyboardTypeNumberPad;
cardNumberItem.hideIcon = !isEditing; cardNumberItem.hideIcon = !isEditing;
cardNumberItem.delegate = self;
// Hide credit card icon when editing. // Hide credit card icon when editing.
if (!isEditing) { if (!isEditing) {
cardNumberItem.identifyingIcon = cardNumberItem.identifyingIcon =
...@@ -415,6 +396,7 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -415,6 +396,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
nicknameItem.textFieldEnabled = isEditing; nicknameItem.textFieldEnabled = isEditing;
nicknameItem.keyboardType = UIKeyboardTypeDefault; nicknameItem.keyboardType = UIKeyboardTypeDefault;
nicknameItem.hideIcon = !isEditing; nicknameItem.hideIcon = !isEditing;
nicknameItem.delegate = self;
return nicknameItem; return nicknameItem;
} }
......
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