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

Side by Side Diff: ios/chrome/browser/payments/payment_request_edit_view_controller.mm

Issue 2744823003: [Payment Request] Generic edit form (Closed)
Patch Set: Created 3 years, 9 months 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/payments/payment_request_edit_view_controller.h"
6
7 #include "base/logging.h"
8 #import "base/mac/foundation_util.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "components/autofill/core/browser/validation.h"
11 #include "components/strings/grit/components_strings.h"
12 #import "ios/chrome/browser/payments/cells/payments_text_item.h"
13 #import "ios/chrome/browser/ui/settings/autofill_edit_accessory_view.h"
14 #import "ios/chrome/browser/ui/settings/cells/autofill_edit_item.h"
15 #import "ios/chrome/browser/ui/uikit_ui_util.h"
16 #include "ios/chrome/grit/ios_theme_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18
19 #if !defined(__has_feature) || !__has_feature(objc_arc)
20 #error "This file requires ARC support."
21 #endif
22
23 namespace {
24
25 AutofillEditCell* AutofillEditCellForTextField(UITextField* textField) {
26 for (UIView* view = textField; view; view = [view superview]) {
27 AutofillEditCell* cell = base::mac::ObjCCast<AutofillEditCell>(view);
28 if (cell)
29 return cell;
30 }
31
32 // There has to be a cell associated with this text field.
33 NOTREACHED();
34 return nil;
35 }
36
37 } // namespace
38
39 @interface PaymentRequestEditViewController ()<AutofillEditAccessoryDelegate> {
40 // The currently focused cell. May be nil.
41 __weak AutofillEditCell* _currentEditingCell;
42
43 AutofillEditAccessoryView* _accessoryView;
44
45 // The PaymentRequest object owning an instance of web::PaymentRequest as
46 // provided by the page invoking the Payment Request API. This is a weak
47 // pointer and should outlive this class.
48 PaymentRequest* _paymentRequest;
49 }
50 @end
51
52 @implementation PaymentRequestEditViewController
53
54 - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest {
55 self = [super initWithStyle:CollectionViewControllerStyleAppBar];
56 if (self) {
57 DCHECK(paymentRequest);
58 _paymentRequest = paymentRequest;
59 _accessoryView = [[AutofillEditAccessoryView alloc] initWithDelegate:self];
60 }
61 return self;
62 }
63
64 - (void)viewDidAppear:(BOOL)animated {
65 [super viewDidAppear:animated];
66 [[NSNotificationCenter defaultCenter]
67 addObserver:self
68 selector:@selector(keyboardDidShow)
69 name:UIKeyboardDidShowNotification
70 object:nil];
71 }
72
73 - (void)viewWillDisappear:(BOOL)animated {
74 [super viewWillDisappear:animated];
75 [[NSNotificationCenter defaultCenter]
76 removeObserver:self
77 name:UIKeyboardDidShowNotification
78 object:nil];
79 }
80
81 #pragma mark - CollectionViewController methods
82
83 - (void)loadModel {
84 [super loadModel];
85 CollectionViewModel* model = self.collectionViewModel;
86
87 // Iterate over the field definitions and add the respective sections and
88 // items.
89 for (const auto& field : [self editorFields]) {
90 [model addSectionWithIdentifier:field.section_id];
91 AutofillEditItem* item =
92 [[AutofillEditItem alloc] initWithType:field.item_type];
93 NSString* labelFormat = field.required ? @"%@*" : @"%@";
94 item.textFieldName = [NSString
95 stringWithFormat:labelFormat, base::SysUTF16ToNSString(field.label)];
96 item.textFieldEnabled = YES;
97 item.required = field.required;
98 item.autofillType = field.data_type;
99 [model addItem:item toSectionWithIdentifier:field.section_id];
100 }
101 }
102
103 #pragma mark - UITextFieldDelegate
104
105 - (void)textFieldDidBeginEditing:(UITextField*)textField {
106 _currentEditingCell = AutofillEditCellForTextField(textField);
107 [textField setInputAccessoryView:_accessoryView];
108 [self updateAccessoryViewButtonState];
109 }
110
111 - (void)textFieldDidEndEditing:(UITextField*)textField {
112 DCHECK(_currentEditingCell == AutofillEditCellForTextField(textField));
113 [textField setInputAccessoryView:nil];
114 _currentEditingCell = nil;
115 }
116
117 - (BOOL)textFieldShouldReturn:(UITextField*)textField {
118 DCHECK([_currentEditingCell textField] == textField);
119 [self nextPressed];
120 return NO;
121 }
122
123 #pragma mark - AutofillEditAccessoryDelegate
124
125 - (void)nextPressed {
126 AutofillEditCell* nextCell = [self nextTextFieldWithOffset:1];
127 if (nextCell)
128 [nextCell.textField becomeFirstResponder];
129 }
130
131 - (void)previousPressed {
132 AutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1];
133 if (previousCell)
134 [previousCell.textField becomeFirstResponder];
135 }
136
137 - (void)closePressed {
138 [[_currentEditingCell textField] resignFirstResponder];
139 }
140
141 #pragma mark - Protected methods
142
143 - (std::vector<EditorField>)editorFields {
144 return std::vector<EditorField>();
145 }
146
147 - (NSIndexPath*)indexPathForCurrentTextField {
148 DCHECK(_currentEditingCell);
149 NSIndexPath* indexPath =
150 [[self collectionView] indexPathForCell:_currentEditingCell];
151 DCHECK(indexPath);
152 return indexPath;
153 }
154
155 - (NSString*)validateValue:(NSString*)value
156 autofillType:(autofill::ServerFieldType)autofillType
157 required:(BOOL)required {
158 base::string16 errorMessage;
159 if (value.length != 0) {
160 base::string16 valueString = base::SysNSStringToUTF16(value);
161 autofillType == autofill::CREDIT_CARD_NUMBER
162 ? autofill::IsValidCreditCardNumberForBasicCardNetworks(
163 valueString, _paymentRequest->supported_card_networks(),
164 &errorMessage)
165 : autofill::IsValidForType(valueString, autofillType, &errorMessage);
166 return base::SysUTF16ToNSString(errorMessage);
167 }
168
169 if (required) {
170 errorMessage = l10n_util::GetStringUTF16(
171 IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE);
172 }
173
174 return base::SysUTF16ToNSString(errorMessage);
175 }
176
177 - (void)addOrRemoveErrorItemWithType:(NSInteger)itemType
178 errorMessage:(NSString*)errorMessage
179 inSectionWithIdentifier:(NSInteger)sectionIdentifier {
180 CollectionViewModel* model = self.collectionViewModel;
181 if ([model hasItemForItemType:itemType sectionIdentifier:sectionIdentifier]) {
182 [model removeItemWithType:itemType
183 fromSectionWithIdentifier:sectionIdentifier];
184 }
185
186 if (errorMessage.length != 0) {
187 PaymentsTextItem* errorMessageItem =
188 [[PaymentsTextItem alloc] initWithType:itemType];
189 errorMessageItem.text = errorMessage;
190 errorMessageItem.image = NativeImage(IDR_IOS_PAYMENTS_WARNING);
191 [model addItem:errorMessageItem toSectionWithIdentifier:sectionIdentifier];
192 }
193
194 // Update the entire section.
195 NSInteger section = [model sectionForSectionIdentifier:sectionIdentifier];
196 [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:section]];
197 }
198
199 #pragma mark - Helper methods
200
201 - (NSIndexPath*)indexPathWithSectionOffset:(NSInteger)offset
202 fromPath:(NSIndexPath*)indexPath {
203 DCHECK(indexPath);
204 DCHECK(offset);
205
206 NSInteger nextSection = [indexPath section] + offset;
207 if (nextSection >= 0 &&
208 nextSection < [[self collectionView] numberOfSections])
209 return [NSIndexPath indexPathForRow:[indexPath row] inSection:nextSection];
210
211 return nil;
212 }
213
214 - (AutofillEditCell*)nextTextFieldWithOffset:(NSInteger)offset {
215 UICollectionView* collectionView = [self collectionView];
216 NSIndexPath* currentCellPath = [self indexPathForCurrentTextField];
217 DCHECK(currentCellPath);
218 for (NSIndexPath* nextCellPath =
219 [self indexPathWithSectionOffset:offset fromPath:currentCellPath];
220 nextCellPath;
221 nextCellPath =
222 [self indexPathWithSectionOffset:offset fromPath:nextCellPath]) {
223 id nextCell = [collectionView cellForItemAtIndexPath:nextCellPath];
224 if ([nextCell isMemberOfClass:[AutofillEditCell class]]) {
225 return base::mac::ObjCCastStrict<AutofillEditCell>(
226 [collectionView cellForItemAtIndexPath:nextCellPath]);
227 }
228 }
229 return nil;
230 }
231
232 - (void)updateAccessoryViewButtonState {
233 AutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1];
234 [[_accessoryView previousButton] setEnabled:previousCell != nil];
235
236 AutofillEditCell* nextCell = [self nextTextFieldWithOffset:1];
237 [[_accessoryView nextButton] setEnabled:nextCell != nil];
238 }
239
240 #pragma mark - Keyboard handling
241
242 - (void)keyboardDidShow {
243 [self.collectionView scrollRectToVisible:[_currentEditingCell frame]
244 animated:YES];
245 }
246
247 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698