Chromium Code Reviews| Index: chrome/browser/ui/cocoa/autofill/autofill_section_container.mm |
| diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm |
| index d67a1b3b5fca636ad9ba70ce9bae75476568bdc7..6ed132bbff2ad1277a7377a3cd7c12d157727410 100644 |
| --- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm |
| +++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm |
| @@ -72,10 +72,10 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| @interface AutofillSectionContainer () |
| -// A text field has been edited or activated - inform the delegate that it's |
| -// time to show a suggestion popup & possibly reset the validity of the input. |
| -- (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| - edited:(BOOL)edited; |
| +// An input field has been edited or activated - inform the delegate and |
| +// possibly reset the validity of the input (if it's a textfield). |
| +- (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| + edited:(BOOL)edited; |
| // Convenience method to retrieve a field type via the control's tag. |
| - (autofill::ServerFieldType)fieldTypeForControl:(NSControl*)control; |
| @@ -104,8 +104,8 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| // Create a button offering input suggestions. |
| - (MenuButton*)makeSuggestionButton; |
| -// Create a view with all inputs requested by |delegate_|. Autoreleased. |
| -- (LayoutView*)makeInputControls; |
| +// Create a view with all inputs requested by |delegate_| and resets |input_|. |
| +- (void)makeInputControls; |
| // Refresh all field icons based on |delegate_| status. |
| - (void)updateFieldIcons; |
| @@ -159,27 +159,8 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| - (void)loadView { |
| - // Keep a list of weak pointers to DetailInputs. |
| - const autofill::DetailInputs& inputs = |
| - delegate_->RequestedFieldsForSection(section_); |
| - |
| - // Reverse the order of all the inputs. |
| - for (int i = inputs.size() - 1; i >= 0; --i) { |
| - detailInputs_.push_back(&(inputs[i])); |
| - } |
| + [self makeInputControls]; |
| - // Then right the reversal in each row. |
| - std::vector<const autofill::DetailInput*>::iterator it; |
| - for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) { |
| - std::vector<const autofill::DetailInput*>::iterator start = it; |
| - while (it != detailInputs_.end() && |
| - (*it)->length != autofill::DetailInput::LONG) { |
| - ++it; |
| - } |
| - std::reverse(start, it); |
| - } |
| - |
| - inputs_.reset([[self makeInputControls] retain]); |
| base::string16 labelText = delegate_->LabelForSection(section_); |
| label_.reset( |
| [[self makeDetailSectionLabel:base::SysUTF16ToNSString(labelText)] |
| @@ -288,7 +269,7 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| - (void)onMouseDown:(NSControl<AutofillInputField>*)field { |
| - [self textfieldEditedOrActivated:field edited:NO]; |
| + [self fieldEditedOrActivated:field edited:NO]; |
| [validationDelegate_ updateMessageForField:field]; |
| } |
| @@ -297,7 +278,7 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| - (void)didChange:(id)sender { |
| - [self textfieldEditedOrActivated:sender edited:YES]; |
| + [self fieldEditedOrActivated:sender edited:YES]; |
| } |
| - (void)didEndEditing:(id)sender { |
| @@ -419,17 +400,10 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| #pragma mark Internal API for AutofillSectionContainer. |
| -- (void)textfieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| - edited:(BOOL)edited { |
| - AutofillTextField* textfield = |
| - base::mac::ObjCCastStrict<AutofillTextField>(field); |
| - |
| - // This only applies to textfields. |
| - if (!textfield) |
| - return; |
| - |
| +- (void)fieldEditedOrActivated:(NSControl<AutofillInputField>*)field |
| + edited:(BOOL)edited { |
| autofill::ServerFieldType type = [self fieldTypeForControl:field]; |
| - base::string16 fieldValue = base::SysNSStringToUTF16([textfield fieldValue]); |
| + base::string16 fieldValue = base::SysNSStringToUTF16([field fieldValue]); |
| // Get the frame rectangle for the designated field, in screen coordinates. |
| NSRect textFrameInScreen = [field convertRect:[field bounds] toView:nil]; |
| @@ -449,22 +423,27 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| fieldValue, |
| edited); |
| - // If the field is marked as invalid, check if the text is now valid. |
| - // Many fields (i.e. CC#) are invalid for most of the duration of editing, |
| - // so flagging them as invalid prematurely is not helpful. However, |
| - // correcting a minor mistake (i.e. a wrong CC digit) should immediately |
| - // result in validation - positive user feedback. |
| - if ([textfield invalid] && edited) { |
| - base::string16 message = delegate_->InputValidityMessage(section_, |
| - type, |
| - fieldValue); |
| - [textfield setValidityMessage:base::SysUTF16ToNSString(message)]; |
| - [validationDelegate_ updateMessageForField:textfield]; |
| - |
| - // If the field transitioned from invalid to valid, re-validate the group, |
| - // since inter-field checks become meaningful with valid fields. |
| - if (![textfield invalid]) |
| - [self validateFor:autofill::VALIDATE_EDIT]; |
| + AutofillTextField* textfield = base::mac::ObjCCast<AutofillTextField>(field); |
| + |
| + // This only applies to textfields. |
| + if (textfield) { |
|
groby-ooo-7-16
2014/01/14 19:37:07
You can skip this if - [textfield invalid] will ev
Dan Beam
2014/01/15 03:10:48
we talked about this offline and will change after
|
| + // If the field is marked as invalid, check if the text is now valid. |
| + // Many fields (i.e. CC#) are invalid for most of the duration of editing, |
| + // so flagging them as invalid prematurely is not helpful. However, |
| + // correcting a minor mistake (i.e. a wrong CC digit) should immediately |
| + // result in validation - positive user feedback. |
| + if ([textfield invalid] && edited) { |
| + base::string16 message = delegate_->InputValidityMessage(section_, |
| + type, |
| + fieldValue); |
| + [textfield setValidityMessage:base::SysUTF16ToNSString(message)]; |
| + [validationDelegate_ updateMessageForField:textfield]; |
| + |
| + // If the field transitioned from invalid to valid, re-validate the group, |
| + // since inter-field checks become meaningful with valid fields. |
| + if (![textfield invalid]) |
| + [self validateFor:autofill::VALIDATE_EDIT]; |
| + } |
| } |
| // Update the icon if necessary. |
| @@ -485,7 +464,7 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| return detailInputs_[i]; |
| } |
| // TODO(groby): Needs to be NOTREACHED. Can't, due to the fact that tests |
| - // blindly call setFieldValue:forInput:, even for non-existing inputs. |
| + // blindly call setFieldValue:forType:, even for non-existing inputs. |
| return NULL; |
| } |
| @@ -514,23 +493,29 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| - (void)updateAndClobber:(BOOL)shouldClobber { |
| - const autofill::DetailInputs& updatedInputs = |
| - delegate_->RequestedFieldsForSection(section_); |
| - |
| - for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); |
| - iter != updatedInputs.end(); |
| - ++iter) { |
| - NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; |
| - DCHECK(field); |
| + if (shouldClobber) { |
| + [self makeInputControls]; |
| - if (shouldClobber || [field isDefault]) { |
| - [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; |
| + id delegate = [[view_ window] windowController]; |
| + if ([delegate respondsToSelector:@selector(requestRelayout)]) { |
| + [delegate performSelector:@selector(requestRelayout)]; |
| + } |
| + } else { |
| + const autofill::DetailInputs& updatedInputs = |
| + delegate_->RequestedFieldsForSection(section_); |
| + |
| + for (autofill::DetailInputs::const_iterator iter = updatedInputs.begin(); |
| + iter != updatedInputs.end(); |
| + ++iter) { |
| + NSControl<AutofillInputField>* field = [inputs_ viewWithTag:iter->type]; |
| + DCHECK(field); |
| + if ([field isDefault]) |
| + [field setFieldValue:base::SysUTF16ToNSString(iter->initial_value)]; |
| } |
| - if (shouldClobber) |
| - [field setValidityMessage:@""]; |
| + [self updateFieldIcons]; |
| } |
| + |
| [self updateEditability]; |
| - [self updateFieldIcons]; |
| [self modelChanged]; |
| } |
| @@ -571,7 +556,29 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| // TODO(estade): we should be using Chrome-style constrained window padding |
| // values. |
| -- (LayoutView*)makeInputControls { |
| +- (void)makeInputControls { |
| + detailInputs_.clear(); |
| + |
| + // Keep a list of weak pointers to DetailInputs. |
| + const autofill::DetailInputs& inputs = |
| + delegate_->RequestedFieldsForSection(section_); |
| + |
| + // Reverse the order of all the inputs. |
| + for (int i = inputs.size() - 1; i >= 0; --i) { |
| + detailInputs_.push_back(&(inputs[i])); |
| + } |
| + |
| + // Then right the reversal in each row. |
| + std::vector<const autofill::DetailInput*>::iterator it; |
| + for (it = detailInputs_.begin(); it < detailInputs_.end(); ++it) { |
| + std::vector<const autofill::DetailInput*>::iterator start = it; |
| + while (it != detailInputs_.end() && |
| + (*it)->length != autofill::DetailInput::LONG) { |
| + ++it; |
| + } |
| + std::reverse(start, it); |
| + } |
| + |
| base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]); |
| [view setLayoutManager: |
| scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))]; |
| @@ -625,11 +632,11 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| NSString* tooltipText = |
| base::SysUTF16ToNSString(delegate_->TooltipForField(input.type)); |
| if ([tooltipText length] > 0) { |
| - DCHECK(!tooltipController_); |
| - DCHECK(!tooltipField_); |
| - tooltipController_.reset( |
| - [[AutofillTooltipController alloc] |
| - initWithArrowLocation:info_bubble::kTopRight]); |
| + if (!tooltipController_) { |
| + tooltipController_.reset( |
| + [[AutofillTooltipController alloc] |
| + initWithArrowLocation:info_bubble::kTopRight]); |
| + } |
| tooltipField_ = field.get(); |
| NSImage* icon = |
| ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| @@ -659,7 +666,11 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| [self updateFieldIcons]; |
| - return view.autorelease(); |
| + |
| + if (inputs_) |
| + [[self view] replaceSubview:inputs_ with:view]; |
|
groby-ooo-7-16
2014/01/14 19:37:07
I'd post requestRelayout from here.
Dan Beam
2014/01/15 03:10:48
Done.
|
| + |
| + inputs_ = view; |
| } |
| - (void)updateFieldIcons { |
| @@ -682,13 +693,13 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| } |
| - (void)updateEditability { |
| - |
| base::scoped_nsobject<NSMutableArray> controls([[NSMutableArray alloc] init]); |
| [self addInputsToArray:controls]; |
| for (NSControl<AutofillInputField>* control in controls.get()) { |
| autofill::ServerFieldType type = [self fieldTypeForControl:control]; |
| const autofill::DetailInput* input = [self detailInputForType:type]; |
| - [control setEnabled:delegate_->InputIsEditable(*input, section_)]; |
| + if (input) |
| + [control setEnabled:delegate_->InputIsEditable(*input, section_)]; |
| } |
| } |
| @@ -716,7 +727,7 @@ bool ShouldOverwriteComboboxes(autofill::DialogSection section, |
| NSControl<AutofillInputField>* field = [inputs_ viewWithTag:type]; |
| if (field) { |
| [[field window] makeFirstResponder:field]; |
| - [self textfieldEditedOrActivated:field edited:NO]; |
| + [self fieldEditedOrActivated:field edited:NO]; |
| } |
| } |