OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" | 5 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | 10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 } | 93 } |
94 return nil; | 94 return nil; |
95 } | 95 } |
96 | 96 |
97 - (void)modelChanged { | 97 - (void)modelChanged { |
98 for (AutofillSectionContainer* details in details_.get()) | 98 for (AutofillSectionContainer* details in details_.get()) |
99 [details modelChanged]; | 99 [details modelChanged]; |
100 } | 100 } |
101 | 101 |
102 - (BOOL)validate { | 102 - (BOOL)validate { |
103 // Account for a subtle timing issue. -validate is called from the dialog's | |
104 // -accept. -accept then hides the dialog. If the data does not validate the | |
105 // dialog is then reshown, focusing on the first invalid field. This happens | |
106 // without running the message loop, so windowWillClose has not fired when | |
107 // the dialog and error bubble is reshown, leading to a missign error bubble. | |
Ilya Sherman
2014/01/08 21:48:33
nit: "missign" -> "missing"
| |
108 // Resetting the anchor view here forces the bubble to show. | |
109 errorBubbleAnchorView_ = nil; | |
110 | |
103 bool allValid = true; | 111 bool allValid = true; |
104 for (AutofillSectionContainer* details in details_.get()) { | 112 for (AutofillSectionContainer* details in details_.get()) { |
105 if (![[details view] isHidden]) | 113 if (![[details view] isHidden]) |
106 allValid = [details validateFor:autofill::VALIDATE_FINAL] && allValid; | 114 allValid = [details validateFor:autofill::VALIDATE_FINAL] && allValid; |
107 } | 115 } |
108 return allValid; | 116 return allValid; |
109 } | 117 } |
110 | 118 |
111 - (NSView*)firstInvalidField { | 119 - (NSView*)firstInvalidField { |
112 return [self firstEditableFieldMatchingBlock: | 120 return [self firstEditableFieldMatchingBlock: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 } | 157 } |
150 | 158 |
151 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { | 159 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { |
152 DCHECK_EQ([notification object], [errorBubbleController_ window]); | 160 DCHECK_EQ([notification object], [errorBubbleController_ window]); |
153 | 161 |
154 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 162 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
155 [center removeObserver:self | 163 [center removeObserver:self |
156 name:NSWindowWillCloseNotification | 164 name:NSWindowWillCloseNotification |
157 object:[errorBubbleController_ window]]; | 165 object:[errorBubbleController_ window]]; |
158 errorBubbleController_ = nil; | 166 errorBubbleController_ = nil; |
167 errorBubbleAnchorView_ = nil; | |
159 } | 168 } |
160 | 169 |
161 - (void)showErrorBubbleForField:(NSControl<AutofillInputField>*)field { | 170 - (void)showErrorBubbleForField:(NSControl<AutofillInputField>*)field { |
171 // If there is already a bubble controller handling this field, reuse. | |
172 if (errorBubbleController_ && errorBubbleAnchorView_ == field) { | |
173 [errorBubbleController_ setMessage:[field validityMessage]]; | |
174 | |
175 return; | |
176 } | |
177 | |
162 if (errorBubbleController_) | 178 if (errorBubbleController_) |
163 [errorBubbleController_ close]; | 179 [errorBubbleController_ close]; |
164 DCHECK(!errorBubbleController_); | 180 DCHECK(!errorBubbleController_); |
165 NSWindow* parentWindow = [field window]; | 181 NSWindow* parentWindow = [field window]; |
166 DCHECK(parentWindow); | 182 DCHECK(parentWindow); |
167 errorBubbleController_ = | 183 errorBubbleController_ = |
168 [[AutofillBubbleController alloc] | 184 [[AutofillBubbleController alloc] |
169 initWithParentWindow:parentWindow | 185 initWithParentWindow:parentWindow |
170 message:[field validityMessage]]; | 186 message:[field validityMessage]]; |
171 | 187 |
(...skipping 24 matching lines...) Expand all Loading... | |
196 | 212 |
197 } else { | 213 } else { |
198 anchorPoint = NSMakePoint(NSMinX(viewRect), NSMinY(viewRect)); | 214 anchorPoint = NSMakePoint(NSMinX(viewRect), NSMinY(viewRect)); |
199 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopLeft]; | 215 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopLeft]; |
200 [[errorBubbleController_ bubble] setAlignment: | 216 [[errorBubbleController_ bubble] setAlignment: |
201 info_bubble::kAlignLeftEdgeToAnchorEdge]; | 217 info_bubble::kAlignLeftEdgeToAnchorEdge]; |
202 } | 218 } |
203 [errorBubbleController_ setAnchorPoint: | 219 [errorBubbleController_ setAnchorPoint: |
204 [parentWindow convertBaseToScreen:anchorPoint]]; | 220 [parentWindow convertBaseToScreen:anchorPoint]]; |
205 | 221 |
222 errorBubbleAnchorView_ = field; | |
206 [errorBubbleController_ showWindow:self]; | 223 [errorBubbleController_ showWindow:self]; |
207 } | 224 } |
208 | 225 |
209 - (void)hideErrorBubble { | 226 - (void)hideErrorBubble { |
210 [errorBubble_ setHidden:YES]; | 227 [errorBubble_ setHidden:YES]; |
211 } | 228 } |
212 | 229 |
213 - (void)updateMessageForField:(NSControl<AutofillInputField>*)field { | 230 - (void)updateMessageForField:(NSControl<AutofillInputField>*)field { |
214 // Ignore fields that are not first responder. Testing this is a bit | 231 // Ignore fields that are not first responder. Testing this is a bit |
215 // convoluted, since for NSTextFields with firstResponder status, the | 232 // convoluted, since for NSTextFields with firstResponder status, the |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 } | 280 } |
264 | 281 |
265 selectedField = field; | 282 selectedField = field; |
266 selectedFieldOrigin = fieldOrigin; | 283 selectedFieldOrigin = fieldOrigin; |
267 } | 284 } |
268 | 285 |
269 return selectedField; | 286 return selectedField; |
270 } | 287 } |
271 | 288 |
272 @end | 289 @end |
OLD | NEW |