summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 07:53:29 +0000
committerdbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 07:53:29 +0000
commit71b6272a6adf06fcd70f402cb8bfd83aa986449e (patch)
tree6097460ef7c4afb8f6f930fc0eb51a05bface6ef
parent1c881566bfc202570c21eca4902c69711d8219f1 (diff)
downloadchromium_src-71b6272a6adf06fcd70f402cb8bfd83aa986449e.zip
chromium_src-71b6272a6adf06fcd70f402cb8bfd83aa986449e.tar.gz
chromium_src-71b6272a6adf06fcd70f402cb8bfd83aa986449e.tar.bz2
Hide validation bubble when Autofill popup shows (so they're not both showing
simultaneously). BUG=306197 R=estade@chromium.org,groby@chromium.org Review URL: https://codereview.chromium.org/26901005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228338 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc24
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc12
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.h1
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc4
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_view.h3
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_view_delegate.h3
-rw-r--r--chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h1
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_details_container.h5
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_details_container.mm40
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h2
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm8
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_main_container.h3
-rw-r--r--chrome/browser/ui/cocoa/autofill/autofill_main_container.mm4
-rw-r--r--chrome/browser/ui/views/autofill/autofill_dialog_views.cc10
-rw-r--r--chrome/browser/ui/views/autofill/autofill_dialog_views.h1
15 files changed, 104 insertions, 17 deletions
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
index fb8a53d..2fbc3d7 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
@@ -559,6 +559,30 @@ IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
}
}
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
+ EXPECT_TRUE(controller()->ShouldShowErrorBubble());
+
+ CreditCard card(test::GetCreditCard());
+ ASSERT_FALSE(card.IsVerified());
+ controller()->GetTestingManager()->AddTestingCreditCard(&card);
+
+ const DetailInputs& cc_inputs =
+ controller()->RequestedFieldsForSection(SECTION_CC);
+ const DetailInput& cc_number_input = cc_inputs[0];
+ ASSERT_EQ(CREDIT_CARD_NUMBER, cc_number_input.type);
+
+ TestableAutofillDialogView* view = controller()->GetTestableView();
+ view->SetTextContentsOfInput(
+ cc_number_input,
+ card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
+
+ view->ActivateInput(cc_number_input);
+ EXPECT_FALSE(controller()->ShouldShowErrorBubble());
+
+ controller()->FocusMoved();
+ EXPECT_TRUE(controller()->ShouldShowErrorBubble());
+}
+
// Tests that credit card number is disabled while editing a Wallet instrument.
IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, WalletCreditCardDisabled) {
std::vector<std::string> usernames;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 5ea39f9..90a99ae 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -1897,17 +1897,24 @@ void AutofillDialogControllerImpl::UserEditedOrActivatedInput(
base::i18n::IsRTL() ?
base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT);
popup_controller_->set_hide_on_outside_click(true);
+
+ // |input_showing_popup_| must be set before calling |Show()|.
+ input_showing_popup_ = input;
+
popup_controller_->Show(popup_values,
popup_labels,
popup_icons,
popup_ids);
- input_showing_popup_ = input;
}
void AutofillDialogControllerImpl::FocusMoved() {
HidePopup();
}
+bool AutofillDialogControllerImpl::ShouldShowErrorBubble() const {
+ return !input_showing_popup_;
+}
+
void AutofillDialogControllerImpl::ViewClosed() {
GetManager()->RemoveObserver(this);
@@ -2078,6 +2085,9 @@ content::WebContents* AutofillDialogControllerImpl::GetWebContents() {
void AutofillDialogControllerImpl::OnPopupShown(
content::RenderWidgetHost::KeyPressEventCallback* callback) {
+ ScopedViewUpdates update(view_.get());
+ view_->UpdateErrorBubble();
+
GetMetricLogger().LogDialogPopupEvent(AutofillMetrics::DIALOG_POPUP_SHOWN);
}
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
index d752901..ad057f4 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
@@ -153,6 +153,7 @@ class AutofillDialogControllerImpl : public AutofillDialogViewDelegate,
virtual bool HandleKeyPressEventInInput(
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual void FocusMoved() OVERRIDE;
+ virtual bool ShouldShowErrorBubble() const OVERRIDE;
virtual void ViewClosed() OVERRIDE;
virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE;
virtual void LinkClicked(const GURL& url) OVERRIDE;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
index debb347..799d7a2 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
@@ -180,6 +180,10 @@ class TestAutofillDialogView : public AutofillDialogView {
EXPECT_GE(updates_started_, 1);
}
+ virtual void UpdateErrorBubble() OVERRIDE {
+ EXPECT_GE(updates_started_, 1);
+ }
+
virtual void FillSection(DialogSection section,
const DetailInput& originating_input) OVERRIDE {};
virtual void GetUserInput(DialogSection section, DetailOutputMap* output)
diff --git a/chrome/browser/ui/autofill/autofill_dialog_view.h b/chrome/browser/ui/autofill/autofill_dialog_view.h
index b1012d6..aa27201 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_view.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_view.h
@@ -65,6 +65,9 @@ class AutofillDialogView {
// Called when the contents of a section have changed.
virtual void UpdateSection(DialogSection section) = 0;
+ // Updates the error bubble for this view.
+ virtual void UpdateErrorBubble() = 0;
+
// Fills the given section with Autofill data that was triggered by a user
// interaction with |originating_input|.
virtual void FillSection(DialogSection section,
diff --git a/chrome/browser/ui/autofill/autofill_dialog_view_delegate.h b/chrome/browser/ui/autofill/autofill_dialog_view_delegate.h
index 3bfe14e..bcb33c6 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_view_delegate.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_view_delegate.h
@@ -167,6 +167,9 @@ class AutofillDialogViewDelegate {
// Called when focus has changed position within the view.
virtual void FocusMoved() = 0;
+ // Whether the view should show a validation error bubble.
+ virtual bool ShouldShowErrorBubble() const = 0;
+
// Miscellany ----------------------------------------------------------------
// Called when the view has been closed.
diff --git a/chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h b/chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h
index 34c662ebe..99ccfc5 100644
--- a/chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h
+++ b/chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h
@@ -69,6 +69,7 @@ class MockAutofillDialogViewDelegate : public AutofillDialogViewDelegate {
MOCK_METHOD1(HandleKeyPressEventInInput,
bool(const content::NativeWebKeyboardEvent& event));
MOCK_METHOD0(FocusMoved, void());
+ MOCK_CONST_METHOD0(ShouldShowErrorBubble, bool());
MOCK_METHOD0(ViewClosed, void());
MOCK_METHOD0(CurrentNotifications,std::vector<DialogNotification>());
MOCK_METHOD1(LinkClicked, void(const GURL&));
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
index 9c90833..2cd82cd 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
@@ -31,7 +31,7 @@ class AutofillDialogViewDelegate;
base::scoped_nsobject<NSMutableArray> details_;
// An info bubble to display validation errors.
- base::scoped_nsobject<InfoBubbleView> infoBubble_;
+ base::scoped_nsobject<InfoBubbleView> errorBubble_;
autofill::AutofillDialogViewDelegate* delegate_; // Not owned.
}
@@ -42,6 +42,9 @@ class AutofillDialogViewDelegate;
// Retrieve the container for the specified |section|.
- (AutofillSectionContainer*)sectionForId:(autofill::DialogSection)section;
+// Called when |errorBubble_| needs to be updated.
+- (void)updateErrorBubble;
+
// Called when the delegate-maintained suggestions model has changed.
- (void)modelChanged;
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
index 6996225..3adf3ce 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
@@ -61,21 +61,21 @@ SkColor const kWarningColor = 0xffde4932; // SkColorSetRGB(0xde, 0x49, 0x32);
for (AutofillSectionContainer* container in details_.get())
[[scrollView_ documentView] addSubview:[container view]];
- infoBubble_.reset([[InfoBubbleView alloc] initWithFrame:NSZeroRect]);
- [infoBubble_ setBackgroundColor:
+ errorBubble_.reset([[InfoBubbleView alloc] initWithFrame:NSZeroRect]);
+ [errorBubble_ setBackgroundColor:
gfx::SkColorToCalibratedNSColor(kWarningColor)];
- [infoBubble_ setArrowLocation:info_bubble::kTopCenter];
- [infoBubble_ setAlignment:info_bubble::kAlignArrowToAnchor];
- [infoBubble_ setHidden:YES];
+ [errorBubble_ setArrowLocation:info_bubble::kTopCenter];
+ [errorBubble_ setAlignment:info_bubble::kAlignArrowToAnchor];
+ [errorBubble_ setHidden:YES];
base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
[label setEditable:NO];
[label setBordered:NO];
[label setDrawsBackground:NO];
[label setTextColor:[NSColor whiteColor]];
- [infoBubble_ addSubview:label];
+ [errorBubble_ addSubview:label];
- [[scrollView_ documentView] addSubview:infoBubble_];
+ [[scrollView_ documentView] addSubview:errorBubble_];
[self performLayout];
}
@@ -126,16 +126,22 @@ SkColor const kWarningColor = 0xffde4932; // SkColorSetRGB(0xde, 0x49, 0x32);
return allValid;
}
+- (void)updateErrorBubble {
+ if (!delegate_->ShouldShowErrorBubble())
+ [errorBubble_ setHidden:YES];
+}
+
// TODO(groby): Unify with BaseBubbleController's originFromAnchor:view:.
- (NSPoint)originFromAnchorView:(NSView*)view {
// All math done in window coordinates, since views might be flipped.
NSRect viewRect = [view convertRect:[view bounds] toView:nil];
NSPoint anchorPoint =
NSMakePoint(NSMidX(viewRect), NSMinY(viewRect));
- NSRect bubbleRect = [infoBubble_ convertRect:[infoBubble_ bounds] toView:nil];
+ NSRect bubbleRect = [errorBubble_ convertRect:[errorBubble_ bounds]
+ toView:nil];
NSPoint bubbleOrigin = NSMakePoint(anchorPoint.x - NSWidth(bubbleRect) / 2.0,
anchorPoint.y - NSHeight(bubbleRect));
- return [[infoBubble_ superview] convertPoint:bubbleOrigin fromView:nil];
+ return [[errorBubble_ superview] convertPoint:bubbleOrigin fromView:nil];
}
- (void)updateMessageForField:(NSControl<AutofillInputField>*)field {
@@ -144,25 +150,29 @@ SkColor const kWarningColor = 0xffde4932; // SkColorSetRGB(0xde, 0x49, 0x32);
// firstResponder is a subview of the NSTextField, not the field itself.
NSView* firstResponderView =
base::mac::ObjCCast<NSView>([[field window] firstResponder]);
- if (![firstResponderView isDescendantOf:field]) {
+ if (![firstResponderView isDescendantOf:field])
+ return;
+
+ if (!delegate_->ShouldShowErrorBubble()) {
+ DCHECK([errorBubble_ isHidden]);
return;
}
if ([field invalid]) {
const CGFloat labelInset = 3.0;
- NSTextField* label = [[infoBubble_ subviews] objectAtIndex:0];
+ NSTextField* label = [[errorBubble_ subviews] objectAtIndex:0];
[label setStringValue:[field validityMessage]];
[label sizeToFit];
NSSize bubbleSize = [label frame].size;
bubbleSize.width += 2 * labelInset;
bubbleSize.height += 2 * labelInset + info_bubble::kBubbleArrowHeight;
- [infoBubble_ setFrameSize:bubbleSize];
+ [errorBubble_ setFrameSize:bubbleSize];
[label setFrameOrigin:NSMakePoint(labelInset, labelInset)];
- [infoBubble_ setFrameOrigin:[self originFromAnchorView:field]];
- [infoBubble_ setHidden:NO];
+ [errorBubble_ setFrameOrigin:[self originFromAnchorView:field]];
+ [errorBubble_ setHidden:NO];
} else {
- [infoBubble_ setHidden:YES];
+ [errorBubble_ setHidden:YES];
}
}
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
index 601a40b..4cded2c 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
@@ -50,6 +50,7 @@ class AutofillDialogCocoa : public AutofillDialogView,
virtual void UpdateForErrors() OVERRIDE;
virtual void UpdateNotificationArea() OVERRIDE;
virtual void UpdateSection(DialogSection section) OVERRIDE;
+ virtual void UpdateErrorBubble() OVERRIDE;
virtual void FillSection(DialogSection section,
const DetailInput& originating_input) OVERRIDE;
virtual void GetUserInput(DialogSection section,
@@ -149,6 +150,7 @@ class AutofillDialogCocoa : public AutofillDialogView,
- (content::NavigationController*)showSignIn;
- (void)hideSignIn;
- (void)modelChanged;
+- (void)updateErrorBubble;
@end
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
index 4d8541aa..640f46d 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
@@ -149,6 +149,10 @@ void AutofillDialogCocoa::ModelChanged() {
[sheet_delegate_ modelChanged];
}
+void AutofillDialogCocoa::UpdateErrorBubble() {
+ [sheet_delegate_ updateErrorBubble];
+}
+
TestableAutofillDialogView* AutofillDialogCocoa::GetTestableView() {
return this;
}
@@ -546,6 +550,10 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
[mainContainer_ modelChanged];
}
+- (void)updateErrorBubble {
+ [mainContainer_ updateErrorBubble];
+}
+
@end
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container.h b/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
index 559f548..b2e72c7 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
@@ -68,6 +68,9 @@ namespace autofill {
// Called when there are changes to the notification area.
- (void)updateNotificationArea;
+// Called when the error bubble needs to be updated.
+- (void)updateErrorBubble;
+
// Validates form input data.
- (BOOL)validate;
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
index 452270c..76a3b47 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
@@ -289,6 +289,10 @@
(delegate_->ShouldSaveInChrome() ? NSOnState : NSOffState)];
}
+- (void)updateErrorBubble {
+ [detailsContainer_ updateErrorBubble];
+}
+
@end
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index 64c2235..3fba317 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -1421,6 +1421,11 @@ void AutofillDialogViews::UpdateSection(DialogSection section) {
UpdateSectionImpl(section, true);
}
+void AutofillDialogViews::UpdateErrorBubble() {
+ if (!delegate_->ShouldShowErrorBubble())
+ HideErrorBubble();
+}
+
void AutofillDialogViews::FillSection(DialogSection section,
const DetailInput& originating_input) {
DetailsGroup* group = GroupForSection(section);
@@ -2166,6 +2171,11 @@ void AutofillDialogViews::ShowErrorBubbleForViewIfNecessary(views::View* view) {
if (!view->GetWidget())
return;
+ if (!delegate_->ShouldShowErrorBubble()) {
+ DCHECK(!error_bubble_);
+ return;
+ }
+
std::map<views::View*, base::string16>::iterator error_message =
validity_map_.find(view);
if (error_message != validity_map_.end()) {
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.h b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
index 4e64fea..ef59102 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.h
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
@@ -85,6 +85,7 @@ class AutofillDialogViews : public AutofillDialogView,
virtual void UpdateForErrors() OVERRIDE;
virtual void UpdateNotificationArea() OVERRIDE;
virtual void UpdateSection(DialogSection section) OVERRIDE;
+ virtual void UpdateErrorBubble() OVERRIDE;
virtual void FillSection(DialogSection section,
const DetailInput& originating_input) OVERRIDE;
virtual void GetUserInput(DialogSection section,