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

Side by Side Diff: chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc

Issue 520743002: The password bubble should fade out on click on the web page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix the nit Created 6 years, 3 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h" 5 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
6 6
7 #include "chrome/browser/chrome_notification_types.h" 7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/ui/browser.h" 8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_finder.h" 9 #include "chrome/browser/ui/browser_finder.h"
10 #include "chrome/browser/ui/browser_window.h" 10 #include "chrome/browser/ui/browser_window.h"
11 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" 11 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" 12 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
13 #include "chrome/browser/ui/views/frame/browser_view.h" 13 #include "chrome/browser/ui/views/frame/browser_view.h"
14 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 14 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
15 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h" 15 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h"
16 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h" 16 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
17 #include "chrome/grit/generated_resources.h" 17 #include "chrome/grit/generated_resources.h"
18 #include "components/password_manager/core/common/password_manager_ui.h" 18 #include "components/password_manager/core/common/password_manager_ui.h"
19 #include "content/public/browser/notification_source.h" 19 #include "content/public/browser/notification_source.h"
20 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
21 #include "ui/aura/window.h" 21 #include "ui/aura/window.h"
22 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/models/combobox_model.h" 23 #include "ui/base/models/combobox_model.h"
24 #include "ui/base/resource/resource_bundle.h" 24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/compositor/layer_animation_observer.h"
26 #include "ui/compositor/scoped_layer_animation_settings.h"
25 #include "ui/gfx/text_utils.h" 27 #include "ui/gfx/text_utils.h"
26 #include "ui/views/controls/button/blue_button.h" 28 #include "ui/views/controls/button/blue_button.h"
27 #include "ui/views/controls/button/label_button.h" 29 #include "ui/views/controls/button/label_button.h"
28 #include "ui/views/controls/combobox/combobox.h" 30 #include "ui/views/controls/combobox/combobox.h"
29 #include "ui/views/controls/styled_label.h" 31 #include "ui/views/controls/styled_label.h"
30 #include "ui/views/layout/fill_layout.h" 32 #include "ui/views/layout/fill_layout.h"
31 #include "ui/views/layout/grid_layout.h" 33 #include "ui/views/layout/grid_layout.h"
32 #include "ui/views/layout/layout_constants.h" 34 #include "ui/views/layout/layout_constants.h"
33 35
34 36
35 // Helpers -------------------------------------------------------------------- 37 // Helpers --------------------------------------------------------------------
36 38
37 namespace { 39 namespace {
38 40
39 // The number of seconds the inactive bubble should stay alive. 41 // The number of seconds the bubble needs to fade out.
40 const int kBubbleCloseDelay = 15; 42 const int kBubbleFadeDelay = 2;
41 43
42 const int kDesiredBubbleWidth = 370; 44 const int kDesiredBubbleWidth = 370;
43 45
44 enum ColumnSetType { 46 enum ColumnSetType {
45 // | | (FILL, FILL) | | 47 // | | (FILL, FILL) | |
46 // Used for the bubble's header, the credentials list, and for simple 48 // Used for the bubble's header, the credentials list, and for simple
47 // messages like "No passwords". 49 // messages like "No passwords".
48 SINGLE_VIEW_COLUMN_SET = 0, 50 SINGLE_VIEW_COLUMN_SET = 0,
49 51
50 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | | 52 // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 529 }
528 530
529 virtual ~WebContentMouseHandler() { 531 virtual ~WebContentMouseHandler() {
530 aura::Window* window = GetWebContentsWindow(); 532 aura::Window* window = GetWebContentsWindow();
531 if (window) 533 if (window)
532 window->RemovePreTargetHandler(this); 534 window->RemovePreTargetHandler(this);
533 } 535 }
534 536
535 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { 537 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
536 if (event->type() == ui::ET_MOUSE_PRESSED) 538 if (event->type() == ui::ET_MOUSE_PRESSED)
537 bubble_->OnWebContentClicked(); 539 bubble_->StartFadingOut();
538 } 540 }
539 541
540 private: 542 private:
541 aura::Window* GetWebContentsWindow() { 543 aura::Window* GetWebContentsWindow() {
542 content::WebContents* web_contents = bubble_->model()->web_contents(); 544 content::WebContents* web_contents = bubble_->model()->web_contents();
543 return web_contents ? web_contents->GetNativeView() : NULL; 545 return web_contents ? web_contents->GetNativeView() : NULL;
544 } 546 }
545 547
546 ManagePasswordsBubbleView* bubble_; 548 ManagePasswordsBubbleView* bubble_;
547 549
548 DISALLOW_COPY_AND_ASSIGN(WebContentMouseHandler); 550 DISALLOW_COPY_AND_ASSIGN(WebContentMouseHandler);
549 }; 551 };
550 552
553 // ManagePasswordsBubbleView::FadeOutObserver ---------------------------------
554
555 // The class notifies the bubble when it faded out completely.
556 class ManagePasswordsBubbleView::FadeOutObserver
557 : public ui::ImplicitAnimationObserver {
558 public:
559 explicit FadeOutObserver(ManagePasswordsBubbleView* bubble)
560 : bubble_(bubble) {
561 }
562
563 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
564 bubble_->OnBubbleDisappeared();
565 }
566
567 private:
568 ManagePasswordsBubbleView* bubble_;
569
570 DISALLOW_COPY_AND_ASSIGN(FadeOutObserver);
571 };
572
551 // ManagePasswordsBubbleView -------------------------------------------------- 573 // ManagePasswordsBubbleView --------------------------------------------------
552 574
553 // static 575 // static
554 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ = 576 ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ =
555 NULL; 577 NULL;
556 578
557 // static 579 // static
558 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents, 580 void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents,
559 DisplayReason reason) { 581 DisplayReason reason) {
560 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 582 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
(...skipping 22 matching lines...) Expand all
583 605
584 // Adjust for fullscreen after creation as it relies on the content size. 606 // Adjust for fullscreen after creation as it relies on the content size.
585 if (is_fullscreen) { 607 if (is_fullscreen) {
586 manage_passwords_bubble_->AdjustForFullscreen( 608 manage_passwords_bubble_->AdjustForFullscreen(
587 browser_view->GetBoundsInScreen()); 609 browser_view->GetBoundsInScreen());
588 } 610 }
589 if (reason == AUTOMATIC) 611 if (reason == AUTOMATIC)
590 manage_passwords_bubble_->GetWidget()->ShowInactive(); 612 manage_passwords_bubble_->GetWidget()->ShowInactive();
591 else 613 else
592 manage_passwords_bubble_->GetWidget()->Show(); 614 manage_passwords_bubble_->GetWidget()->Show();
593 manage_passwords_bubble_->StartTimerIfNecessary();
594 } 615 }
595 616
596 // static 617 // static
597 void ManagePasswordsBubbleView::CloseBubble() { 618 void ManagePasswordsBubbleView::CloseBubble() {
598 if (manage_passwords_bubble_) 619 if (manage_passwords_bubble_)
599 manage_passwords_bubble_->Close(); 620 manage_passwords_bubble_->Close();
600 } 621 }
601 622
602 // static 623 // static
603 void ManagePasswordsBubbleView::ActivateBubble() { 624 void ManagePasswordsBubbleView::ActivateBubble() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // The bubble's padding from the screen edge, used in fullscreen. 666 // The bubble's padding from the screen edge, used in fullscreen.
646 const int kFullscreenPaddingEnd = 20; 667 const int kFullscreenPaddingEnd = 20;
647 const size_t bubble_half_width = width() / 2; 668 const size_t bubble_half_width = width() / 2;
648 const int x_pos = base::i18n::IsRTL() ? 669 const int x_pos = base::i18n::IsRTL() ?
649 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : 670 screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd :
650 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; 671 screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd;
651 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); 672 SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0));
652 } 673 }
653 674
654 void ManagePasswordsBubbleView::Close() { 675 void ManagePasswordsBubbleView::Close() {
676 fadeout_observer_.reset();
677 mouse_handler_.reset();
655 GetWidget()->Close(); 678 GetWidget()->Close();
656 } 679 }
657 680
658 void ManagePasswordsBubbleView::Init() { 681 void ManagePasswordsBubbleView::Init() {
659 views::FillLayout* layout = new views::FillLayout(); 682 views::FillLayout* layout = new views::FillLayout();
660 SetLayoutManager(layout); 683 SetLayoutManager(layout);
661 684
662 Refresh(); 685 Refresh();
663 } 686 }
664 687
665 void ManagePasswordsBubbleView::WindowClosing() { 688 void ManagePasswordsBubbleView::WindowClosing() {
666 // Close() closes the window asynchronously, so by the time we reach here, 689 // Close() closes the window asynchronously, so by the time we reach here,
667 // |manage_passwords_bubble_| may have already been reset. 690 // |manage_passwords_bubble_| may have already been reset.
668 if (manage_passwords_bubble_ == this) 691 if (manage_passwords_bubble_ == this)
669 manage_passwords_bubble_ = NULL; 692 manage_passwords_bubble_ = NULL;
670 } 693 }
671 694
672 void ManagePasswordsBubbleView::OnWidgetActivationChanged(views::Widget* widget, 695 void ManagePasswordsBubbleView::OnWidgetActivationChanged(views::Widget* widget,
673 bool active) { 696 bool active) {
674 if (active && widget == GetWidget()) 697 if (active && widget == GetWidget())
675 timer_.Stop(); 698 CancelFadingOut();
676 BubbleDelegateView::OnWidgetActivationChanged(widget, active); 699 BubbleDelegateView::OnWidgetActivationChanged(widget, active);
677 } 700 }
678 701
679 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() { 702 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() {
680 return initially_focused_view_; 703 return initially_focused_view_;
681 } 704 }
682 705
683 void ManagePasswordsBubbleView::OnMouseEntered(const ui::MouseEvent& event) { 706 void ManagePasswordsBubbleView::OnMouseEntered(const ui::MouseEvent& event) {
684 timer_.Stop(); 707 CancelFadingOut();
685 }
686
687 void ManagePasswordsBubbleView::OnMouseExited(const ui::MouseEvent& event) {
688 StartTimerIfNecessary();
689 } 708 }
690 709
691 void ManagePasswordsBubbleView::Refresh() { 710 void ManagePasswordsBubbleView::Refresh() {
692 RemoveAllChildViews(true); 711 RemoveAllChildViews(true);
693 initially_focused_view_ = NULL; 712 initially_focused_view_ = NULL;
694 if (password_manager::ui::IsPendingState(model()->state())) { 713 if (password_manager::ui::IsPendingState(model()->state())) {
695 if (never_save_passwords_) 714 if (never_save_passwords_)
696 AddChildView(new ConfirmNeverView(this)); 715 AddChildView(new ConfirmNeverView(this));
697 else 716 else
698 AddChildView(new PendingView(this)); 717 AddChildView(new PendingView(this));
699 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) { 718 } else if (model()->state() == password_manager::ui::BLACKLIST_STATE) {
700 AddChildView(new BlacklistedView(this)); 719 AddChildView(new BlacklistedView(this));
701 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) { 720 } else if (model()->state() == password_manager::ui::CONFIRMATION_STATE) {
702 AddChildView(new SaveConfirmationView(this)); 721 AddChildView(new SaveConfirmationView(this));
703 } else { 722 } else {
704 AddChildView(new ManageView(this)); 723 AddChildView(new ManageView(this));
705 } 724 }
706 GetLayoutManager()->Layout(this); 725 GetLayoutManager()->Layout(this);
707 // If we refresh the existing bubble we may want to restart the timer. 726 CancelFadingOut();
708 if (GetWidget())
709 StartTimerIfNecessary();
710 } 727 }
711 728
712 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() { 729 void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() {
713 if (model()->best_matches().empty()) { 730 if (model()->best_matches().empty()) {
714 // Skip confirmation if there are no existing passwords for this site. 731 // Skip confirmation if there are no existing passwords for this site.
715 NotifyConfirmedNeverForThisSite(); 732 NotifyConfirmedNeverForThisSite();
716 } else { 733 } else {
717 never_save_passwords_ = true; 734 never_save_passwords_ = true;
718 Refresh(); 735 Refresh();
719 } 736 }
720 } 737 }
721 738
722 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() { 739 void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() {
723 model()->OnNeverForThisSiteClicked(); 740 model()->OnNeverForThisSiteClicked();
724 Close(); 741 Close();
725 } 742 }
726 743
727 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() { 744 void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() {
728 never_save_passwords_ = false; 745 never_save_passwords_ = false;
729 Refresh(); 746 Refresh();
730 } 747 }
731 748
732 void ManagePasswordsBubbleView::StartTimerIfNecessary() { 749 void ManagePasswordsBubbleView::StartFadingOut() {
733 // Active bubble will stay visible until it loses focus. 750 if (fadeout_observer_)
734 if (GetWidget()->IsActive())
735 return; 751 return;
736 timer_.Start(FROM_HERE, 752 aura::Window* window = GetWidget()->GetNativeView();
737 base::TimeDelta::FromSeconds(kBubbleCloseDelay), 753 ui::ScopedLayerAnimationSettings animator(window->layer()->GetAnimator());
738 this, 754 fadeout_observer_.reset(new FadeOutObserver(this));
739 &ManagePasswordsBubbleView::Close); 755 animator.AddObserver(fadeout_observer_.get());
756 animator.SetTransitionDuration(
757 base::TimeDelta::FromSeconds(kBubbleFadeDelay));
758 window->layer()->SetOpacity(0);
740 } 759 }
741 760
742 void ManagePasswordsBubbleView::OnWebContentClicked() { 761 void ManagePasswordsBubbleView::CancelFadingOut() {
762 if (!fadeout_observer_)
763 return;
764 fadeout_observer_.reset();
765 aura::Window* window = GetWidget()->GetNativeView();
766 window->layer()->SetOpacity(1);
767 }
768
769 void ManagePasswordsBubbleView::OnBubbleDisappeared() {
743 Close(); 770 Close();
744 } 771 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698