diff options
-rw-r--r-- | chrome/browser/password_manager.cc | 65 | ||||
-rw-r--r-- | chrome/browser/password_manager.h | 43 | ||||
-rw-r--r-- | chrome/browser/tab_contents.cc | 10 | ||||
-rw-r--r-- | chrome/browser/tab_contents.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.cc | 37 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.h | 10 | ||||
-rw-r--r-- | chrome/common/notification_types.h | 14 |
8 files changed, 97 insertions, 90 deletions
diff --git a/chrome/browser/password_manager.cc b/chrome/browser/password_manager.cc index f046773..7b675d6 100644 --- a/chrome/browser/password_manager.cc +++ b/chrome/browser/password_manager.cc @@ -25,7 +25,6 @@ void PasswordManager::RegisterUserPrefs(PrefService* prefs) { PasswordManager::PasswordManager(WebContents* web_contents) : web_contents_(web_contents), - current_bar_(NULL), observer_(NULL), login_managers_deleter_(&pending_login_managers_) { password_manager_enabled_.Init(prefs::kPasswordManagerEnabled, @@ -33,7 +32,8 @@ PasswordManager::PasswordManager(WebContents* web_contents) } PasswordManager::~PasswordManager() { - CloseBars(); + // Remove any InfoBars we may be showing. + web_contents_->RemoveInfoBar(this); } void PasswordManager::ProvisionallySavePassword(PasswordForm form) { @@ -112,8 +112,7 @@ void PasswordManager::DidStopLoading() { return; if (pending_save_manager_->IsNewLogin()) { - // Transfer ownership of the pending_save_manager_ to the PasswordBar. - ReplaceInfoBar(new SavePasswordBar(pending_save_manager_.release(), this)); + web_contents_->AddInfoBar(this); } else { // If the save is not a new username entry, then we just want to save this // data (since the user already has related data saved), so don't prompt. @@ -182,45 +181,41 @@ void PasswordManager::Autofill(const PasswordForm& form_for_autofill, } } -void PasswordManager::CloseBars() { - if (current_bar_) - current_bar_->Close(); +// PasswordManager, ConfirmInfoBarDelegate implementation: --------------------- + +void PasswordManager::InfoBarClosed() { + pending_save_manager_.reset(NULL); +} + +std::wstring PasswordManager::GetMessageText() const { + return l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT); } -void PasswordManager::ReplaceInfoBar(InfoBarItemView* bar) { - // TODO(brettw) The password manager should not have to know about info bars. - CloseBars(); - InfoBarView* view = web_contents_->view()->GetInfoBarView(); - view->AddChildView(bar); - current_bar_ = bar; +SkBitmap* PasswordManager::GetIcon() const { + return ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_INFOBAR_SAVE_PASSWORD); } -PasswordManager::SavePasswordBar - ::SavePasswordBar(PasswordFormManager* form_manager, - PasswordManager* password_manager) - : form_manager_(form_manager), - password_manager_(password_manager), - InfoBarConfirmView( - l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT)) { - SetOKButtonLabel(l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_BUTTON)); - SetCancelButtonLabel(l10n_util::GetString( - IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON)); - ResourceBundle &rb = ResourceBundle::GetSharedInstance(); - SetIcon(*rb.GetBitmapNamed(IDR_INFOBAR_SAVE_PASSWORD)); +int PasswordManager::GetButtons() const { + return BUTTON_OK | BUTTON_CANCEL; } -PasswordManager::SavePasswordBar::~SavePasswordBar() { - password_manager_->current_bar_ = NULL; - if (form_manager_) - delete form_manager_; +std::wstring PasswordManager::GetButtonLabel(InfoBarButton button) const { + if (button == BUTTON_OK) + return l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_BUTTON); + if (button == BUTTON_CANCEL) + return l10n_util::GetString(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON); + NOTREACHED(); + return std::wstring(); } -void PasswordManager::SavePasswordBar::OKButtonPressed() { - form_manager_->Save(); - BeginClose(); +void PasswordManager::Accept() { + pending_save_manager_->Save(); + web_contents_->RemoveInfoBar(this); } -void PasswordManager::SavePasswordBar::CancelButtonPressed() { - form_manager_->PermanentlyBlacklist(); - BeginClose(); +void PasswordManager::Cancel() { + pending_save_manager_->PermanentlyBlacklist(); + web_contents_->RemoveInfoBar(this); } + diff --git a/chrome/browser/password_manager.h b/chrome/browser/password_manager.h index ecdac61..584ffff 100644 --- a/chrome/browser/password_manager.h +++ b/chrome/browser/password_manager.h @@ -6,7 +6,7 @@ #define CHROME_BROWSER_PASSWORD_MANAGER_H__ #include "base/scoped_ptr.h" -#include "chrome/browser/views/info_bar_confirm_view.h" +#include "chrome/browser/infobar_delegate.h" #include "chrome/browser/password_form_manager.h" #include "chrome/browser/views/login_view.h" #include "chrome/common/pref_member.h" @@ -21,7 +21,8 @@ class WebContents; // receiving password form data from the renderer and managing the password // database through the WebDataService. The PasswordManager is a LoginModel // for purposes of supporting HTTP authentication dialogs. -class PasswordManager : public views::LoginModel { +class PasswordManager : public views::LoginModel, + public ConfirmInfoBarDelegate { public: static void RegisterUserPrefs(PrefService* prefs); @@ -34,9 +35,6 @@ class PasswordManager : public views::LoginModel { const PasswordFormMap& best_matches, const PasswordForm* const preferred_match) const; - // Closes any visible password manager UI - void CloseBars(); - // Notification that the user navigated away from the current page. // Unless this is a password form submission, for our purposes this // means we're done with the current page, so we can clean-up. @@ -63,32 +61,15 @@ class PasswordManager : public views::LoginModel { } private: - // The Info Bar UI that prompts the user to save a password. - friend class SavePasswordBar; - class SavePasswordBar : public InfoBarConfirmView { - public: - SavePasswordBar(PasswordFormManager* form_manager, - PasswordManager* password_manager); - virtual ~SavePasswordBar(); - - // InfoBarConfirmView overrides. - virtual void OKButtonPressed(); - virtual void CancelButtonPressed(); - - private: - PasswordFormManager* form_manager_; - PasswordManager* password_manager_; - - DISALLOW_EVIL_CONSTRUCTORS(SavePasswordBar); - }; - - // Replace the current InfoBar with a new one. Just adds if there is no - // visible InfoBars. - void ReplaceInfoBar(InfoBarItemView* view); - - // The currently visible InfoBar (NULL if none) - InfoBarItemView* current_bar_; - + // Overridden from ConfirmInfoBarDelegate: + virtual void InfoBarClosed(); + virtual std::wstring GetMessageText() const; + virtual SkBitmap* GetIcon() const; + virtual int GetButtons() const; + virtual std::wstring GetButtonLabel(InfoBarButton button) const; + virtual void Accept(); + virtual void Cancel(); + // When a form is "seen" on a page, a PasswordFormManager is created // and stored in this collection until user navigates away from page. typedef std::vector<PasswordFormManager*> LoginManagers; diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc index 510c611..20aa67b 100644 --- a/chrome/browser/tab_contents.cc +++ b/chrome/browser/tab_contents.cc @@ -390,7 +390,7 @@ void TabContents::SetInitialFocus() { void TabContents::AddInfoBar(InfoBarDelegate* delegate) { // Look through the existing InfoBarDelegates we have for a match. If we've // already got one that matches, then we don't add the new one. - for (size_t i = 0; i < infobar_delegate_count(); ++i) { + for (int i = 0; i < infobar_delegate_count(); ++i) { if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate)) return; } @@ -415,10 +415,10 @@ void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) { find(infobar_delegates_.begin(), infobar_delegates_.end(), delegate); if (it != infobar_delegates_.end()) { InfoBarDelegate* delegate = *it; - infobar_delegates_.erase(it); NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED, Source<TabContents>(this), Details<InfoBarDelegate>(delegate)); + infobar_delegates_.erase(it); } // Remove ourselves as an observer if we are tracking no more InfoBars. @@ -590,11 +590,9 @@ void TabContents::ExpireInfoBars( if (!details.is_user_initiated_main_frame_load()) return; - for (size_t i = 0; i < infobar_delegate_count(); ++i) { + for (int i = infobar_delegate_count() - 1; i >= 0; --i) { InfoBarDelegate* delegate = GetInfoBarDelegateAt(i); - if (!TransitionIsReload(details.entry->transition_type()) && - delegate->ShouldCloseOnNavigate()) { + if (delegate->ShouldCloseOnNavigate()) RemoveInfoBar(delegate); - } } } diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h index 6893ee1..2f78a79 100644 --- a/chrome/browser/tab_contents.h +++ b/chrome/browser/tab_contents.h @@ -393,8 +393,8 @@ class TabContents : public PageNavigator, void RemoveInfoBar(InfoBarDelegate* delegate); // Enumeration and access functions. - size_t infobar_delegate_count() const { return infobar_delegates_.size(); } - InfoBarDelegate* GetInfoBarDelegateAt(size_t index) { + int infobar_delegate_count() const { return infobar_delegates_.size(); } + InfoBarDelegate* GetInfoBarDelegateAt(int index) { return infobar_delegates_.at(index); } diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc index 2fe7a35..bb48b12 100644 --- a/chrome/browser/views/infobars/infobar_container.cc +++ b/chrome/browser/views/infobars/infobar_container.cc @@ -103,7 +103,7 @@ void InfoBarContainer::UpdateInfoBars() { // Clear out all the old child views. RemoveAllChildViews(true); - for (size_t i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { + for (int i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i); InfoBar* infobar = delegate->CreateInfoBar(); infobar->set_container(this); @@ -120,7 +120,7 @@ void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) { } void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) { - size_t index = 0; + int index = 0; for (; index < tab_contents_->infobar_delegate_count(); ++index) { if (tab_contents_->GetInfoBarDelegateAt(index) == delegate) break; diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc index 5733d33..c9b6f2e 100644 --- a/chrome/browser/views/infobars/infobars.cc +++ b/chrome/browser/views/infobars/infobars.cc @@ -11,8 +11,10 @@ #include "chrome/common/slide_animation.h" #include "chrome/views/background.h" #include "chrome/views/button.h" +#include "chrome/views/external_focus_tracker.h" #include "chrome/views/image_view.h" #include "chrome/views/label.h" +#include "chrome/views/widget.h" #include "generated_resources.h" @@ -102,6 +104,8 @@ void InfoBar::AnimateClose() { void InfoBar::Close() { GetParent()->RemoveChildView(this); + if (focus_tracker_.get()) + focus_tracker_->FocusLastFocusedExternalView(); if (delegate()) delegate()->InfoBarClosed(); delete this; @@ -122,6 +126,25 @@ void InfoBar::Layout() { } +void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, + views::View* child) { + if (child == this) { + views::Widget* widget = GetWidget(); + if (is_add && widget) { + // When we're added to a view hierarchy within a widget, we create an + // external focus tracker to track what was focused in case we obtain + // focus so that we can restore focus when we're removed. + focus_tracker_.reset( + new views::ExternalFocusTracker(this, + views::FocusManager::GetFocusManager(widget->GetHWND()))); + } else if (focus_tracker_.get()) { + // When we're removed from a view hierarchy, our focus manager is no + // longer valid. + focus_tracker_->SetFocusManager(NULL); + } + } +} + // InfoBar, protected: --------------------------------------------------------- int InfoBar::GetAvailableWidth() const { @@ -199,6 +222,12 @@ ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) cancel_button_(NULL), initialized_(false), AlertInfoBar(delegate) { + ok_button_ = new views::NativeButton( + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); + ok_button_->SetListener(this); + cancel_button_ = new views::NativeButton( + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); + cancel_button_->SetListener(this); } ConfirmInfoBar::~ConfirmInfoBar() { @@ -232,6 +261,7 @@ void ConfirmInfoBar::Layout() { void ConfirmInfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child) { + InfoBar::ViewHierarchyChanged(is_add, parent, child); if (is_add && child == this && !initialized_) { Init(); initialized_ = true; @@ -267,14 +297,7 @@ ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { } void ConfirmInfoBar::Init() { - ok_button_ = new views::NativeButton( - GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); - ok_button_->SetListener(this); AddChildView(ok_button_); - - cancel_button_ = new views::NativeButton( - GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); - cancel_button_->SetListener(this); AddChildView(cancel_button_); } diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h index 1e02f96..7b94735 100644 --- a/chrome/browser/views/infobars/infobars.h +++ b/chrome/browser/views/infobars/infobars.h @@ -13,6 +13,7 @@ class InfoBarContainer; class SlideAnimation; namespace views { class Button; +class ExternalFocusTracker; class ImageView; class Label; } @@ -52,6 +53,11 @@ class InfoBar : public views::View, virtual void Layout(); protected: + // Overridden from views::View: + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); + // Returns the available width of the View for use by child view layout, // excluding the close button. virtual int GetAvailableWidth() const; @@ -76,6 +82,10 @@ class InfoBar : public views::View, // The animation that runs when the InfoBar is opened or closed. scoped_ptr<SlideAnimation> animation_; + // Tracks and stores the last focused view which is not the InfoBar or any of + // its children. Used to restore focus once the InfoBar is closed. + scoped_ptr<views::ExternalFocusTracker> focus_tracker_; + DISALLOW_COPY_AND_ASSIGN(InfoBar); }; diff --git a/chrome/common/notification_types.h b/chrome/common/notification_types.h index c748d36..d6ca458 100644 --- a/chrome/common/notification_types.h +++ b/chrome/common/notification_types.h @@ -200,18 +200,18 @@ enum NotificationType { // No details are expected. NOTIFY_WEB_CONTENTS_DISCONNECTED, - // This message is sent when a new InfoBar is added to a TabContents. The - // source is a Source<TabContents> with a pointer to the TabContents the + // This message is sent when a new InfoBar has been added to a TabContents. + // The source is a Source<TabContents> with a pointer to the TabContents the // InfoBar was added to. The details is a Details<InfoBarDelegate> with a // pointer to an object implementing the InfoBarDelegate interface for the // InfoBar that was added. NOTIFY_TAB_CONTENTS_INFOBAR_ADDED, - // This message is sent when an InfoBar is removed from a TabContents. The - // source is a Source<TabContents> with a pointer to the TabContents the - // InfoBar was removed from. The details is a Details<InfoBarDelegate> with a - // pointer to an object implementing the InfoBarDelegate interface for the - // InfoBar that was removed. + // This message is sent when an InfoBar is about to be removed from a + // TabContents. The source is a Source<TabContents> with a pointer to the + // TabContents the InfoBar was removed from. The details is a + // Details<InfoBarDelegate> with a pointer to an object implementing the + // InfoBarDelegate interface for the InfoBar that was removed. NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED, // This is sent when an externally hosted tab is created. The details contain |