Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Unified Diff: ios/chrome/browser/ui/autofill/cells/cvc_item.mm

Issue 2586993002: Upstream Chrome on iOS source code [3/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/autofill/cells/cvc_item.mm
diff --git a/ios/chrome/browser/ui/autofill/cells/cvc_item.mm b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
new file mode 100644
index 0000000000000000000000000000000000000000..7a69184b17587ae4e6e9bdf1ed73ac9159c3972f
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
@@ -0,0 +1,363 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/autofill/cells/cvc_item.h"
+
+#include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
+#include "ios/chrome/grit/ios_strings.h"
+#import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#import "ios/public/provider/chrome/browser/ui/text_field_styling.h"
+#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
+#import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+// Padding used on the leading and trailing edges of the cell.
+const CGFloat kHorizontalPadding = 16;
+// Padding used on the top and bottom edges of the cell.
+const CGFloat kVerticalPadding = 16;
+// Spacing between elements.
+const CGFloat kUISpacing = 5;
+// Spacing around the CVC container.
+const CGFloat kUICVCSpacing = 20;
+// Height of the different text fields.
+const CGFloat kTextFieldHeight = 50;
+// Width of the date text fields.
+const CGFloat kDateTextFieldWidth = 40;
+// Width of the CVC text field.
+const CGFloat kCVCTextFieldWidth = 60;
+}
+
+@interface CVCCell ()<UITextFieldDelegate>
+@property(nonatomic, strong) UILabel* dateSeparator;
+@property(nonatomic, strong) UIView* dateContainerView;
+@property(nonatomic, strong) UIView* CVCContainerView;
+@property(nonatomic, strong)
+ NSLayoutConstraint* CVCContainerLeadingConstraintWithDate;
+@property(nonatomic, strong)
+ NSLayoutConstraint* CVCContainerLeadingConstraintWithoutDate;
+@end
+
+@implementation CVCItem
+
+@synthesize instructionsText = _instructionsText;
+@synthesize errorMessage = _errorMessage;
+@synthesize monthText = _monthText;
+@synthesize yearText = _yearText;
+@synthesize CVCText = _CVCText;
+@synthesize showDateInput = _showDateInput;
+@synthesize showNewCardButton = _showNewCardButton;
+@synthesize showDateInputError = _showDateInputError;
+@synthesize showCVCInputError = _showCVCInputError;
+@synthesize CVCImageResourceID = _CVCImageResourceID;
+
+- (instancetype)initWithType:(NSInteger)type {
+ self = [super initWithType:type];
+ if (self) {
+ self.cellClass = [CVCCell class];
+ }
+ return self;
+}
+
+#pragma mark CollectionViewItem
+
+- (void)configureCell:(CVCCell*)cell {
+ [super configureCell:cell];
+ cell.instructionsTextLabel.text = self.instructionsText;
+ cell.errorLabel.text = self.errorMessage;
+
+ cell.monthInput.text = self.monthText;
+ cell.yearInput.text = self.yearText;
+ cell.CVCInput.text = self.CVCText;
+
+ cell.dateContainerView.hidden = !self.showDateInput;
+
+ cell.CVCContainerLeadingConstraintWithDate.active = self.showDateInput;
+ cell.CVCContainerLeadingConstraintWithoutDate.active = !self.showDateInput;
+
+ [cell.monthInput setUseErrorStyling:self.showDateInputError];
+ [cell.yearInput setUseErrorStyling:self.showDateInputError];
+ [cell.CVCInput setUseErrorStyling:self.showDateInputError];
+
+ cell.buttonForNewCard.hidden = !self.showNewCardButton;
+
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ cell.CVCImageView.image =
+ rb.GetNativeImageNamed(self.CVCImageResourceID).ToUIImage();
+}
+
+@end
+
+@implementation CVCCell
+
+@synthesize instructionsTextLabel = _instructionsTextLabel;
+@synthesize errorLabel = _errorLabel;
+@synthesize monthInput = _monthInput;
+@synthesize yearInput = _yearInput;
+@synthesize CVCInput = _CVCInput;
+@synthesize buttonForNewCard = _buttonForNewCard;
+@synthesize dateSeparator = _dateSeparator;
+@synthesize CVCImageView = _CVCImageView;
+@synthesize dateContainerView = _dateContainerView;
+@synthesize CVCContainerView = _CVCContainerView;
+@synthesize CVCContainerLeadingConstraintWithDate =
+ _CVCContainerLeadingConstraintWithDate;
+@synthesize CVCContainerLeadingConstraintWithoutDate =
+ _CVCContainerLeadingConstraintWithoutDate;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ UIView* contentView = self.contentView;
+
+ _instructionsTextLabel = [[UILabel alloc] init];
+ _instructionsTextLabel.font =
+ [[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:14];
+ _instructionsTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+ _instructionsTextLabel.numberOfLines = 0;
+ _instructionsTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
+ _instructionsTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
+ [contentView addSubview:_instructionsTextLabel];
+
+ _errorLabel = [[UILabel alloc] init];
+ _errorLabel.font =
+ [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:12];
+ _errorLabel.textColor = [[MDCPalette cr_redPalette] tint500];
+ _errorLabel.numberOfLines = 0;
+ _errorLabel.lineBreakMode = NSLineBreakByWordWrapping;
+ _errorLabel.translatesAutoresizingMaskIntoConstraints = NO;
+ [contentView addSubview:_errorLabel];
+
+ _dateContainerView = [[UIView alloc] init];
+ _dateContainerView.translatesAutoresizingMaskIntoConstraints = NO;
+ [contentView addSubview:_dateContainerView];
+
+ _monthInput =
+ ios::GetChromeBrowserProvider()->CreateStyledTextField(CGRectZero);
+ _monthInput.placeholder = l10n_util::GetNSString(
+ IDS_IOS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH);
+ _monthInput.keyboardType = UIKeyboardTypeNumberPad;
+ _monthInput.delegate = self;
+ _monthInput.translatesAutoresizingMaskIntoConstraints = NO;
+ [_dateContainerView addSubview:_monthInput];
+
+ _dateSeparator = [[UILabel alloc] init];
+ _dateSeparator.text = l10n_util::GetNSString(
+ IDS_AUTOFILL_CARD_UNMASK_EXPIRATION_DATE_SEPARATOR);
+ _dateSeparator.translatesAutoresizingMaskIntoConstraints = NO;
+ [_dateContainerView addSubview:_dateSeparator];
+
+ _yearInput =
+ ios::GetChromeBrowserProvider()->CreateStyledTextField(CGRectZero);
+ _yearInput.placeholder =
+ l10n_util::GetNSString(IDS_IOS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR);
+ _yearInput.keyboardType = UIKeyboardTypeNumberPad;
+ _yearInput.delegate = self;
+ _yearInput.translatesAutoresizingMaskIntoConstraints = NO;
+ [_dateContainerView addSubview:_yearInput];
+
+ _CVCContainerView = [[UIView alloc] init];
+ _CVCContainerView.translatesAutoresizingMaskIntoConstraints = NO;
+ [contentView addSubview:_CVCContainerView];
+
+ _CVCInput =
+ ios::GetChromeBrowserProvider()->CreateStyledTextField(CGRectZero);
+ _CVCInput.placeholder =
+ l10n_util::GetNSString(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC);
+ _CVCInput.keyboardType = UIKeyboardTypeNumberPad;
+ _CVCInput.delegate = self;
+ _CVCInput.translatesAutoresizingMaskIntoConstraints = NO;
+ [_CVCContainerView addSubview:_CVCInput];
+
+ _CVCImageView = [[UIImageView alloc] init];
+ _CVCImageView.translatesAutoresizingMaskIntoConstraints = NO;
+ [_CVCContainerView addSubview:_CVCImageView];
+
+ _buttonForNewCard = [UIButton buttonWithType:UIButtonTypeCustom];
+ _buttonForNewCard.titleLabel.font =
+ [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:12];
+ [_buttonForNewCard
+ setTitle:l10n_util::GetNSString(IDS_AUTOFILL_CARD_UNMASK_NEW_CARD_LINK)
+ forState:UIControlStateNormal];
+ [_buttonForNewCard setTitleColor:[[MDCPalette cr_bluePalette] tint500]
+ forState:UIControlStateNormal];
+ _buttonForNewCard.translatesAutoresizingMaskIntoConstraints = NO;
+ [contentView addSubview:_buttonForNewCard];
+
+ [NSLayoutConstraint activateConstraints:@[
+ // Text label
+ [_instructionsTextLabel.topAnchor
+ constraintEqualToAnchor:contentView.topAnchor
+ constant:kVerticalPadding],
+ [_instructionsTextLabel.leadingAnchor
+ constraintEqualToAnchor:contentView.leadingAnchor
+ constant:kHorizontalPadding],
+ [_instructionsTextLabel.trailingAnchor
+ constraintEqualToAnchor:contentView.trailingAnchor
+ constant:-kHorizontalPadding],
+
+ // Date container
+ [_dateContainerView.topAnchor
+ constraintEqualToAnchor:_instructionsTextLabel.bottomAnchor
+ constant:kUISpacing],
+ [_dateContainerView.leadingAnchor
+ constraintEqualToAnchor:_instructionsTextLabel.leadingAnchor],
+ [_dateContainerView.heightAnchor
+ constraintEqualToConstant:kTextFieldHeight],
+
+ // Date content - Month input
+ [_monthInput.topAnchor
+ constraintEqualToAnchor:_dateContainerView.topAnchor],
+ [_monthInput.leadingAnchor
+ constraintEqualToAnchor:_dateContainerView.leadingAnchor],
+ [_monthInput.widthAnchor constraintEqualToConstant:kDateTextFieldWidth],
+ [_monthInput.bottomAnchor
+ constraintEqualToAnchor:_dateContainerView.bottomAnchor],
+
+ // Date content - Separator
+ [_dateSeparator.leadingAnchor
+ constraintEqualToAnchor:_monthInput.trailingAnchor
+ constant:kUISpacing],
+ [_dateSeparator.firstBaselineAnchor
+ constraintEqualToAnchor:_monthInput.firstBaselineAnchor],
+
+ // Date content = Year input
+ [_yearInput.leadingAnchor
+ constraintEqualToAnchor:_dateSeparator.trailingAnchor
+ constant:kUISpacing],
+ [_yearInput.widthAnchor constraintEqualToAnchor:_monthInput.widthAnchor],
+ [_yearInput.heightAnchor
+ constraintEqualToAnchor:_monthInput.heightAnchor],
+ [_yearInput.firstBaselineAnchor
+ constraintEqualToAnchor:_monthInput.firstBaselineAnchor],
+ [_dateContainerView.trailingAnchor
+ constraintEqualToAnchor:_yearInput.trailingAnchor],
+
+ // CVC container
+ [_CVCContainerView.topAnchor
+ constraintEqualToAnchor:_dateContainerView.topAnchor],
+ [_CVCContainerView.heightAnchor
+ constraintEqualToAnchor:_dateContainerView.heightAnchor],
+ // The horizontal placement of this container is dynamic. The two possible
+ // placements are defined below with
+ // _CVCContainerLeadingConstraintWithDate and
+ // _CVCContainerLeadingConstraintWithoutDate.
+
+ // CVC content - CVC input
+ [_CVCInput.leadingAnchor
+ constraintEqualToAnchor:_CVCContainerView.leadingAnchor],
+ [_CVCInput.widthAnchor constraintEqualToConstant:kCVCTextFieldWidth],
+ [_CVCInput.firstBaselineAnchor
+ constraintEqualToAnchor:_monthInput.firstBaselineAnchor],
+ [_CVCInput.bottomAnchor
+ constraintEqualToAnchor:_CVCContainerView.bottomAnchor],
+
+ // CVC content - CVC image view
+ [_CVCImageView.leadingAnchor
+ constraintEqualToAnchor:_CVCInput.trailingAnchor
+ constant:kUISpacing],
+ [_CVCImageView.centerYAnchor
+ constraintEqualToAnchor:_CVCInput.centerYAnchor],
+ [_CVCContainerView.trailingAnchor
+ constraintEqualToAnchor:_CVCImageView.trailingAnchor],
+
+ // "New Card?" label
+ [_buttonForNewCard.leadingAnchor
+ constraintEqualToAnchor:_CVCContainerView.trailingAnchor
+ constant:kUICVCSpacing],
+ [_buttonForNewCard.firstBaselineAnchor
+ constraintEqualToAnchor:_CVCInput.firstBaselineAnchor],
+
+ // Error label
+ [_errorLabel.topAnchor
+ constraintEqualToAnchor:_dateContainerView.bottomAnchor
+ constant:kUISpacing],
+ [_errorLabel.leadingAnchor
+ constraintEqualToAnchor:_instructionsTextLabel.leadingAnchor],
+ [_errorLabel.trailingAnchor
+ constraintEqualToAnchor:_instructionsTextLabel.trailingAnchor],
+
+ [contentView.bottomAnchor constraintEqualToAnchor:_errorLabel.bottomAnchor
+ constant:kUISpacing],
+ ]];
+
+ _CVCContainerLeadingConstraintWithDate = [_CVCContainerView.leadingAnchor
+ constraintEqualToAnchor:_dateContainerView.trailingAnchor
+ constant:kUICVCSpacing];
+ _CVCContainerLeadingConstraintWithoutDate = [_CVCContainerView.leadingAnchor
+ constraintEqualToAnchor:_instructionsTextLabel.leadingAnchor];
+ }
+ return self;
+}
+
+- (void)prepareForReuse {
+ [super prepareForReuse];
+ self.instructionsTextLabel.text = nil;
+ self.errorLabel.text = nil;
+ self.monthInput.text = nil;
+ [self.monthInput removeTarget:nil
+ action:nil
+ forControlEvents:UIControlEventAllEvents];
+ self.yearInput.text = nil;
+ [self.yearInput removeTarget:nil
+ action:nil
+ forControlEvents:UIControlEventAllEvents];
+ self.CVCInput.text = nil;
+ [self.CVCInput removeTarget:nil
+ action:nil
+ forControlEvents:UIControlEventAllEvents];
+ [self.buttonForNewCard removeTarget:nil
+ action:nil
+ forControlEvents:UIControlEventAllEvents];
+ self.dateContainerView.hidden = YES;
+ self.CVCContainerLeadingConstraintWithDate.active = NO;
+ self.CVCContainerLeadingConstraintWithoutDate.active = YES;
+ [self.monthInput setUseErrorStyling:NO];
+ [self.yearInput setUseErrorStyling:NO];
+ [self.CVCInput setUseErrorStyling:NO];
+ self.buttonForNewCard.hidden = YES;
+ self.CVCImageView.image = nil;
+}
+
+// Implements -layoutSubviews as per instructions in documentation for
+// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
+- (void)layoutSubviews {
+ [super layoutSubviews];
+
+ // Adjust the text labels preferredMaxLayoutWidth when the parent's width
+ // changes, for instance on screen rotation.
+ CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
+ CGFloat labelsPreferredMaxLayoutWidth = parentWidth - 2 * kHorizontalPadding;
+ self.instructionsTextLabel.preferredMaxLayoutWidth =
+ labelsPreferredMaxLayoutWidth;
+ self.errorLabel.preferredMaxLayoutWidth = labelsPreferredMaxLayoutWidth;
+
+ // Re-layout with the new preferred width to allow the labels to adjust their
+ // height.
+ [super layoutSubviews];
+}
+
+#pragma mark - UITextFieldDelegate
+
+// Limit month input to 2 characters. Year input is limited to 4 characters
+// (both 2-digit and 4-digit years are accepted). CVC input is limited to 4
+// characters since CVCs are never longer than that.
+- (BOOL)textField:(UITextField*)textField
+ shouldChangeCharactersInRange:(NSRange)range
+ replacementString:(NSString*)string {
+ if (textField == self.CVCInput || textField == self.yearInput) {
+ return ([textField.text length] + [string length] - range.length) <= 4;
+ } else if (textField == self.monthInput) {
+ return ([textField.text length] + [string length] - range.length) <= 2;
+ }
+ return YES;
+}
+
+@end
« no previous file with comments | « ios/chrome/browser/ui/autofill/cells/cvc_item.h ('k') | ios/chrome/browser/ui/autofill/cells/cvc_item_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698