Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" | 5 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 SaveCardBubbleController* controller) | 56 SaveCardBubbleController* controller) |
| 57 : LocationBarBubbleDelegateView(anchor_view, web_contents), | 57 : LocationBarBubbleDelegateView(anchor_view, web_contents), |
| 58 controller_(controller) { | 58 controller_(controller) { |
| 59 DCHECK(controller); | 59 DCHECK(controller); |
| 60 views::BubbleDialogDelegateView::CreateBubble(this); | 60 views::BubbleDialogDelegateView::CreateBubble(this); |
| 61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD); | 61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD); |
| 62 } | 62 } |
| 63 | 63 |
| 64 SaveCardBubbleViews::~SaveCardBubbleViews() {} | 64 SaveCardBubbleViews::~SaveCardBubbleViews() {} |
| 65 | 65 |
| 66 SaveCardBubbleViews::CurrentFlowStep SaveCardBubbleViews::GetCurrentFlowStep() | |
|
msw
2017/06/29 20:10:25
nit: reorder this (and dtor) to match decl (just b
Jared Saul
2017/07/05 19:36:50
Thanks, nice catch. Also reordered IsDialogButton
| |
| 67 const { | |
| 68 // No legal messages means this is not upload save. | |
| 69 if (controller_->GetLegalMessageLines().empty()) | |
| 70 return LOCAL_SAVE_ONLY_STEP; | |
| 71 // If we're not requesting CVC, this is the only step on the upload path. | |
| 72 if (!controller_->ShouldRequestCvcFromUser()) | |
| 73 return UPLOAD_SAVE_ONLY_STEP; | |
| 74 // Must be on the CVC fix flow on the upload path. | |
| 75 if (view_stack_->size() == 1) | |
| 76 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD; | |
| 77 if (view_stack_->size() == 2) | |
| 78 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC; | |
| 79 // CVC fix flow should never have more than 3 views on the stack. | |
| 80 NOTREACHED(); | |
| 81 return UNKNOWN_STEP; | |
| 82 } | |
| 83 | |
| 66 void SaveCardBubbleViews::Show(DisplayReason reason) { | 84 void SaveCardBubbleViews::Show(DisplayReason reason) { |
| 67 ShowForReason(reason); | 85 ShowForReason(reason); |
| 68 } | 86 } |
| 69 | 87 |
| 70 void SaveCardBubbleViews::Hide() { | 88 void SaveCardBubbleViews::Hide() { |
| 71 controller_ = nullptr; | 89 controller_ = nullptr; |
| 72 CloseBubble(); | 90 CloseBubble(); |
| 73 } | 91 } |
| 74 | 92 |
| 75 views::View* SaveCardBubbleViews::CreateExtraView() { | 93 views::View* SaveCardBubbleViews::CreateExtraView() { |
| 94 if (GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP) | |
| 95 return nullptr; | |
| 96 // Learn More link is only shown on local save bubble. | |
| 76 DCHECK(!learn_more_link_); | 97 DCHECK(!learn_more_link_); |
| 77 learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); | 98 learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); |
| 78 learn_more_link_->SetUnderline(false); | 99 learn_more_link_->SetUnderline(false); |
| 79 learn_more_link_->set_listener(this); | 100 learn_more_link_->set_listener(this); |
| 80 return learn_more_link_; | 101 return learn_more_link_; |
| 81 } | 102 } |
| 82 | 103 |
| 104 int SaveCardBubbleViews::GetDialogButtons() const { | |
|
msw
2017/06/29 20:10:25
nit: reorder to match decl (above CreateExtraView)
Jared Saul
2017/07/05 19:36:50
Done.
| |
| 105 if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP) | |
| 106 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; | |
| 107 // For upload save, don't show the "No thanks" cancel option; use the | |
| 108 // top-right [X] close button for that. | |
| 109 return ui::DIALOG_BUTTON_OK; | |
| 110 } | |
| 111 | |
| 83 views::View* SaveCardBubbleViews::CreateFootnoteView() { | 112 views::View* SaveCardBubbleViews::CreateFootnoteView() { |
| 84 if (controller_->GetLegalMessageLines().empty()) | 113 if (controller_->GetLegalMessageLines().empty()) |
| 85 return nullptr; | 114 return nullptr; |
| 86 | 115 |
| 87 // Use BoxLayout to provide insets around the label. | 116 // Use BoxLayout to provide insets around the label. |
| 88 View* view = new View(); | 117 footnote_view_ = new View(); |
| 89 view->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); | 118 footnote_view_->SetLayoutManager( |
| 119 new views::BoxLayout(views::BoxLayout::kVertical)); | |
| 90 | 120 |
| 91 // Add a StyledLabel for each line of the legal message. | 121 // Add a StyledLabel for each line of the legal message. |
| 92 for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) | 122 for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) |
|
msw
2017/06/29 20:10:24
nit: add curly braces for two-line body
Jared Saul
2017/07/05 19:36:50
Done.
| |
| 93 view->AddChildView(CreateLegalMessageLineLabel(line, this).release()); | 123 footnote_view_->AddChildView( |
| 124 CreateLegalMessageLineLabel(line, this).release()); | |
| 94 | 125 |
| 95 return view; | 126 // If on the first step of the 2-step upload flow, hide the footer area until |
| 127 // it's time to actually accept the dialog and ToS. | |
| 128 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD) | |
| 129 footnote_view_->SetVisible(false); | |
| 130 | |
| 131 return footnote_view_; | |
| 96 } | 132 } |
| 97 | 133 |
| 98 bool SaveCardBubbleViews::Accept() { | 134 bool SaveCardBubbleViews::Accept() { |
| 99 // The main content ViewStack for local save and happy-path upload save should | 135 // The main content ViewStack for local save and happy-path upload save should |
| 100 // only ever have 1 View on it. Upload save can have a second View if CVC | 136 // only ever have 1 View on it. Upload save can have a second View if CVC |
| 101 // needs to be requested. Assert that the ViewStack has no more than 2 Views | 137 // needs to be requested. Assert that the ViewStack has no more than 2 Views |
| 102 // and that if it *does* have 2, it's because CVC is being requested. | 138 // and that if it *does* have 2, it's because CVC is being requested. |
| 103 DCHECK_LE(view_stack_->size(), 2U); | 139 DCHECK_LE(view_stack_->size(), 2U); |
| 104 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser()); | 140 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser()); |
| 105 if (controller_->ShouldRequestCvcFromUser() && view_stack_->size() == 1) { | 141 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD) { |
| 106 // If user accepted upload but more info is needed, push the next view onto | 142 // If user accepted upload but more info is needed, push the next view onto |
| 107 // the stack. | 143 // the stack and update the bubble. |
| 144 DCHECK(controller_); | |
| 145 controller_->SetShowUploadConfirmTitle(true); | |
| 146 GetWidget()->UpdateWindowTitle(); | |
| 108 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); | 147 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); |
| 109 // Disable the Save button until a valid CVC is entered: | 148 // Disable the Save button until a valid CVC is entered: |
| 110 GetDialogClientView()->UpdateDialogButtons(); | 149 GetDialogClientView()->UpdateDialogButtons(); |
| 150 // Make the legal messaging footer appear: | |
| 151 DCHECK(footnote_view_); | |
| 152 footnote_view_->SetVisible(true); | |
| 111 // Resize the bubble if it's grown larger: | 153 // Resize the bubble if it's grown larger: |
| 112 SizeToContents(); | 154 SizeToContents(); |
| 113 return false; | 155 return false; |
| 114 } | 156 } |
| 115 // Otherwise, close the bubble as normal. | 157 // Otherwise, close the bubble as normal. |
| 116 if (controller_) | 158 if (controller_) |
| 117 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text() | 159 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text() |
| 118 : base::string16()); | 160 : base::string16()); |
| 119 return true; | 161 return true; |
| 120 } | 162 } |
| 121 | 163 |
| 122 bool SaveCardBubbleViews::Cancel() { | 164 bool SaveCardBubbleViews::Cancel() { |
| 123 if (controller_) | 165 if (controller_) |
| 124 controller_->OnCancelButton(); | 166 controller_->OnCancelButton(); |
| 125 return true; | 167 return true; |
| 126 } | 168 } |
| 127 | 169 |
| 128 bool SaveCardBubbleViews::Close() { | 170 bool SaveCardBubbleViews::Close() { |
| 129 // Cancel is logged as a different user action than closing, so override | 171 // Cancel is logged as a different user action than closing, so override |
| 130 // Close() to prevent the superclass' implementation from calling Cancel(). | 172 // Close() to prevent the superclass' implementation from calling Cancel(). |
| 131 // Return true to indicate that the bubble can be closed. | 173 // Return true to indicate that the bubble can be closed. |
| 132 return true; | 174 return true; |
| 133 } | 175 } |
| 134 | 176 |
| 135 base::string16 SaveCardBubbleViews::GetDialogButtonLabel( | 177 base::string16 SaveCardBubbleViews::GetDialogButtonLabel( |
| 136 ui::DialogButton button) const { | 178 ui::DialogButton button) const { |
| 137 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK | 179 switch (GetCurrentFlowStep()) { |
| 138 ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT | 180 // Local save has two buttons: |
| 139 : IDS_NO_THANKS); | 181 case LOCAL_SAVE_ONLY_STEP: |
| 182 return l10n_util::GetStringUTF16( | |
| 183 button == ui::DIALOG_BUTTON_OK ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT | |
| 184 : IDS_NO_THANKS); | |
| 185 // Upload save has one button but it can say three different things: | |
| 186 case UPLOAD_SAVE_ONLY_STEP: | |
| 187 DCHECK(button == ui::DIALOG_BUTTON_OK); | |
| 188 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT); | |
| 189 case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD: | |
| 190 DCHECK(button == ui::DIALOG_BUTTON_OK); | |
| 191 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_NEXT); | |
| 192 case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC: | |
| 193 DCHECK(button == ui::DIALOG_BUTTON_OK); | |
| 194 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONFIRM); | |
| 195 default: | |
| 196 NOTREACHED(); | |
| 197 return base::string16(); | |
| 198 } | |
| 140 } | 199 } |
| 141 | 200 |
| 142 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const { | 201 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const { |
| 143 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth)); | 202 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth)); |
| 144 } | 203 } |
| 145 | 204 |
| 205 bool SaveCardBubbleViews::ShouldShowCloseButton() const { | |
| 206 // Local save should have a [No thanks] button, but Upload save should surface | |
|
msw
2017/06/29 20:10:25
nit: Use a consistent "No thanks" / [No thanks] co
Jared Saul
2017/07/05 19:36:50
Done; thanks.
| |
| 207 // the top-right [X] close button instead. | |
| 208 return GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP; | |
| 209 } | |
| 210 | |
| 146 base::string16 SaveCardBubbleViews::GetWindowTitle() const { | 211 base::string16 SaveCardBubbleViews::GetWindowTitle() const { |
| 147 return controller_ ? controller_->GetWindowTitle() : base::string16(); | 212 return controller_ ? controller_->GetWindowTitle() : base::string16(); |
| 148 } | 213 } |
| 149 | 214 |
| 150 void SaveCardBubbleViews::WindowClosing() { | 215 void SaveCardBubbleViews::WindowClosing() { |
| 151 if (controller_) | 216 if (controller_) |
| 152 controller_->OnBubbleClosed(); | 217 controller_->OnBubbleClosed(); |
| 153 } | 218 } |
| 154 | 219 |
| 155 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) { | 220 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 186 | 251 |
| 187 // Create view containing everything except for the footnote. | 252 // Create view containing everything except for the footnote. |
| 188 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { | 253 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { |
| 189 auto view = base::MakeUnique<views::View>(); | 254 auto view = base::MakeUnique<views::View>(); |
| 190 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); | 255 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); |
| 191 | 256 |
| 192 view->SetLayoutManager(new views::BoxLayout( | 257 view->SetLayoutManager(new views::BoxLayout( |
| 193 views::BoxLayout::kVertical, gfx::Insets(), | 258 views::BoxLayout::kVertical, gfx::Insets(), |
| 194 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); | 259 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); |
| 195 | 260 |
| 261 // If applicable, add the upload explanation label. | |
| 262 base::string16 explanation = controller_->GetExplanatoryMessage(); | |
| 263 if (!explanation.empty()) { | |
| 264 views::Label* explanation_label = new views::Label(explanation); | |
| 265 explanation_label->SetMultiLine(true); | |
| 266 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 267 view->AddChildView(explanation_label); | |
| 268 } | |
| 269 | |
| 196 // Add the card type icon, last four digits and expiration date. | 270 // Add the card type icon, last four digits and expiration date. |
| 197 views::View* description_view = new views::View(); | 271 views::View* description_view = new views::View(); |
| 198 description_view->SetLayoutManager(new views::BoxLayout( | 272 description_view->SetLayoutManager(new views::BoxLayout( |
| 199 views::BoxLayout::kHorizontal, gfx::Insets(), | 273 views::BoxLayout::kHorizontal, gfx::Insets(), |
| 200 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); | 274 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); |
| 201 view->AddChildView(description_view); | 275 view->AddChildView(description_view); |
| 202 | 276 |
| 203 const CreditCard& card = controller_->GetCard(); | 277 const CreditCard& card = controller_->GetCard(); |
| 204 views::ImageView* card_type_icon = new views::ImageView(); | 278 views::ImageView* card_type_icon = new views::ImageView(); |
| 205 card_type_icon->SetImage( | 279 card_type_icon->SetImage( |
| 206 ResourceBundle::GetSharedInstance() | 280 ResourceBundle::GetSharedInstance() |
| 207 .GetImageNamed(CreditCard::IconResourceId(card.network())) | 281 .GetImageNamed(CreditCard::IconResourceId(card.network())) |
| 208 .AsImageSkia()); | 282 .AsImageSkia()); |
| 209 card_type_icon->SetTooltipText(card.NetworkForDisplay()); | 283 card_type_icon->SetTooltipText(card.NetworkForDisplay()); |
| 210 card_type_icon->SetBorder( | 284 card_type_icon->SetBorder( |
| 211 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10))); | 285 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10))); |
| 212 description_view->AddChildView(card_type_icon); | 286 description_view->AddChildView(card_type_icon); |
| 213 | 287 |
| 214 description_view->AddChildView(new views::Label( | |
| 215 base::string16(kMidlineEllipsis) + card.LastFourDigits())); | |
| 216 description_view->AddChildView( | 288 description_view->AddChildView( |
| 217 new views::Label(card.AbbreviatedExpirationDateForDisplay())); | 289 new views::Label(card.NetworkAndLastFourDigits())); |
| 218 | |
| 219 // Optionally add label that will contain an explanation for upload. | |
| 220 base::string16 explanation = controller_->GetExplanatoryMessage(); | |
| 221 if (!explanation.empty()) { | |
| 222 views::Label* explanation_label = new views::Label(explanation); | |
| 223 explanation_label->SetMultiLine(true); | |
| 224 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 225 view->AddChildView(explanation_label); | |
| 226 } | |
| 227 | 290 |
| 228 return view; | 291 return view; |
| 229 } | 292 } |
| 230 | 293 |
| 231 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { | 294 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { |
| 232 auto request_cvc_view = base::MakeUnique<views::View>(); | 295 auto request_cvc_view = base::MakeUnique<views::View>(); |
| 296 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); | |
| 297 | |
| 298 request_cvc_view->SetLayoutManager(new views::BoxLayout( | |
| 299 views::BoxLayout::kVertical, gfx::Insets(), | |
| 300 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); | |
| 233 request_cvc_view->SetBackground(views::CreateThemedSolidBackground( | 301 request_cvc_view->SetBackground(views::CreateThemedSolidBackground( |
| 234 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); | 302 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); |
| 235 views::BoxLayout* layout = | 303 |
| 236 new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(), | 304 views::Label* explanation_label = new views::Label(l10n_util::GetStringUTF16( |
| 237 ChromeLayoutProvider::Get()->GetDistanceMetric( | 305 IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC_EXPLANATION)); |
| 238 views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); | 306 explanation_label->SetMultiLine(true); |
| 307 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 308 request_cvc_view->AddChildView(explanation_label); | |
| 309 | |
| 310 views::View* cvc_entry_view = new views::View(); | |
| 311 views::BoxLayout* layout = new views::BoxLayout( | |
| 312 views::BoxLayout::kHorizontal, gfx::Insets(), | |
| 313 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); | |
| 239 layout->set_cross_axis_alignment( | 314 layout->set_cross_axis_alignment( |
| 240 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); | 315 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); |
| 241 request_cvc_view->SetLayoutManager(layout); | 316 cvc_entry_view->SetLayoutManager(layout); |
| 242 | 317 |
| 243 DCHECK(!cvc_textfield_); | 318 DCHECK(!cvc_textfield_); |
| 244 cvc_textfield_ = CreateCvcTextfield(); | 319 cvc_textfield_ = CreateCvcTextfield(); |
| 245 cvc_textfield_->set_controller(this); | 320 cvc_textfield_->set_controller(this); |
| 246 request_cvc_view->AddChildView(cvc_textfield_); | 321 cvc_entry_view->AddChildView(cvc_textfield_); |
| 247 | 322 |
| 248 views::ImageView* cvc_image = new views::ImageView(); | 323 views::ImageView* cvc_image = new views::ImageView(); |
| 249 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 324 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 250 cvc_image->SetImage( | 325 cvc_image->SetImage( |
| 251 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); | 326 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); |
| 252 request_cvc_view->AddChildView(cvc_image); | 327 cvc_entry_view->AddChildView(cvc_image); |
| 253 | 328 |
| 254 request_cvc_view->AddChildView(new views::Label( | 329 request_cvc_view->AddChildView(cvc_entry_view); |
| 255 l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC))); | |
| 256 | |
| 257 return request_cvc_view; | 330 return request_cvc_view; |
| 258 } | 331 } |
| 259 | 332 |
| 260 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const { | 333 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const { |
| 261 if (button == ui::DIALOG_BUTTON_CANCEL) | 334 if (button == ui::DIALOG_BUTTON_CANCEL) |
| 262 return true; | 335 return true; |
| 263 | 336 |
| 264 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); | 337 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); |
| 265 return !cvc_textfield_ || | 338 return !cvc_textfield_ || |
| 266 controller_->InputCvcIsValid(cvc_textfield_->text()); | 339 controller_->InputCvcIsValid(cvc_textfield_->text()); |
| 267 } | 340 } |
| 268 | 341 |
| 269 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender, | 342 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender, |
| 270 const base::string16& new_contents) { | 343 const base::string16& new_contents) { |
| 271 DCHECK_EQ(cvc_textfield_, sender); | 344 DCHECK_EQ(cvc_textfield_, sender); |
| 272 GetDialogClientView()->UpdateDialogButtons(); | 345 GetDialogClientView()->UpdateDialogButtons(); |
| 273 } | 346 } |
| 274 | 347 |
| 275 void SaveCardBubbleViews::Init() { | 348 void SaveCardBubbleViews::Init() { |
| 276 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); | 349 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); |
| 277 view_stack_ = new ViewStack(); | 350 view_stack_ = new ViewStack(); |
| 278 view_stack_->SetBackground(views::CreateThemedSolidBackground( | 351 view_stack_->SetBackground(views::CreateThemedSolidBackground( |
| 279 view_stack_, ui::NativeTheme::kColorId_BubbleBackground)); | 352 view_stack_, ui::NativeTheme::kColorId_BubbleBackground)); |
| 280 view_stack_->Push(CreateMainContentView(), /*animate=*/false); | 353 view_stack_->Push(CreateMainContentView(), /*animate=*/false); |
| 281 AddChildView(view_stack_); | 354 AddChildView(view_stack_); |
| 282 } | 355 } |
| 283 | 356 |
| 284 } // namespace autofill | 357 } // namespace autofill |
| OLD | NEW |