Commit 431e63b8 authored by mkwst@chromium.org's avatar mkwst@chromium.org

Password bubble: Confirm blacklisting a site if passwords exist.

If a user blacklists a site with existing saved passwords, those
passwords will be deleted. In order to ensure that a user doesn't
accidentally lose data, we prompt them to inform them of the risk, and
ask for confirmation of the decision.

BUG=384155
NOTRY=true

Review URL: https://codereview.chromium.org/347033002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278698 0039d316-1c4b-4281-b951-d872f2087c98
parent ad3a62cd
...@@ -12926,6 +12926,16 @@ Some features may be unavailable. Please check that the profile exists and you ...@@ -12926,6 +12926,16 @@ Some features may be unavailable. Please check that the profile exists and you
<message name="IDS_MANAGE_PASSWORDS_BLACKLISTED_TITLE" desc="The title text that is used in the manage passwords bubble when the current site is blacklisted."> <message name="IDS_MANAGE_PASSWORDS_BLACKLISTED_TITLE" desc="The title text that is used in the manage passwords bubble when the current site is blacklisted.">
Passwords won't be saved Passwords won't be saved
</message> </message>
<message name="IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TITLE" desc="The title text that is used in the manage passwords bubble when confirming blacklisting a site.">
Delete existing saved passwords
</message>
<message name="IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TEXT" desc="The confirmation text that is used in the manage passwords bubble when confirming blacklisting a site.">
Choosing to never save passwords will delete all passwords currently saved for this site.
</message>
<message name="IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_BUTTON" desc="The confirmation button that is used in the manage passwords bubble when confirming blacklisting a site.">
Delete saved passwords
</message>
<message name="IDS_MANAGE_PASSWORDS_NO_PASSWORDS" desc="The text that is used in the manage passwords bubble when all passwords have been deleted."> <message name="IDS_MANAGE_PASSWORDS_NO_PASSWORDS" desc="The text that is used in the manage passwords bubble when all passwords have been deleted.">
No passwords saved. No passwords saved.
</message> </message>
......
...@@ -57,13 +57,14 @@ enum ColumnSetType { ...@@ -57,13 +57,14 @@ enum ColumnSetType {
void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) { void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) {
views::ColumnSet* column_set = layout->AddColumnSet(type); views::ColumnSet* column_set = layout->AddColumnSet(type);
column_set->AddPaddingColumn(0, views::kPanelHorizMargin); column_set->AddPaddingColumn(0, views::kPanelHorizMargin);
int full_width = kDesiredBubbleWidth - (2 * views::kPanelHorizMargin);
switch (type) { switch (type) {
case SINGLE_VIEW_COLUMN_SET: case SINGLE_VIEW_COLUMN_SET:
column_set->AddColumn(views::GridLayout::FILL, column_set->AddColumn(views::GridLayout::FILL,
views::GridLayout::FILL, views::GridLayout::FILL,
0, 0,
views::GridLayout::USE_PREF, views::GridLayout::FIXED,
0, full_width,
0); 0);
break; break;
...@@ -199,12 +200,84 @@ void ManagePasswordsBubbleView::PendingView::OnPerformAction( ...@@ -199,12 +200,84 @@ void ManagePasswordsBubbleView::PendingView::OnPerformAction(
switch (refuse_combobox_->selected_index()) { switch (refuse_combobox_->selected_index()) {
case SavePasswordRefusalComboboxModel::INDEX_NOPE: case SavePasswordRefusalComboboxModel::INDEX_NOPE:
parent_->model()->OnNopeClicked(); parent_->model()->OnNopeClicked();
parent_->Close();
break; break;
case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE: case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE:
parent_->model()->OnNeverForThisSiteClicked(); parent_->NotifyNeverForThisSiteClicked();
break; break;
} }
parent_->Close(); }
// ManagePasswordsBubbleView::ConfirmNeverView ---------------------------------
ManagePasswordsBubbleView::ConfirmNeverView::ConfirmNeverView(
ManagePasswordsBubbleView* parent)
: parent_(parent) {
views::GridLayout* layout = new views::GridLayout(this);
layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
SetLayoutManager(layout);
// Title row.
BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET);
views::Label* title_label = new views::Label(l10n_util::GetStringUTF16(
IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TITLE));
title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
title_label->SetMultiLine(true);
title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::MediumFont));
layout->StartRowWithPadding(
0, SINGLE_VIEW_COLUMN_SET, 0, views::kRelatedControlSmallVerticalSpacing);
layout->AddView(title_label);
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
// Confirmation text.
views::Label* confirmation = new views::Label(l10n_util::GetStringUTF16(
IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TEXT));
confirmation->SetHorizontalAlignment(gfx::ALIGN_LEFT);
confirmation->SetMultiLine(true);
confirmation->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::SmallFont));
layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
layout->AddView(confirmation);
layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
// Confirm and undo buttons.
BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET);
layout->StartRowWithPadding(
0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
confirm_button_ = new views::LabelButton(
this,
l10n_util::GetStringUTF16(
IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_BUTTON));
confirm_button_->SetStyle(views::Button::STYLE_BUTTON);
confirm_button_->SetFontList(
ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::SmallFont));
layout->AddView(confirm_button_);
undo_button_ =
new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_CANCEL));
undo_button_->SetStyle(views::Button::STYLE_BUTTON);
undo_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::SmallFont));
layout->AddView(undo_button_);
// Extra padding for visual awesomeness.
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
}
ManagePasswordsBubbleView::ConfirmNeverView::~ConfirmNeverView() {
}
void ManagePasswordsBubbleView::ConfirmNeverView::ButtonPressed(
views::Button* sender,
const ui::Event& event) {
DCHECK(sender == confirm_button_ || sender == undo_button_);
if (sender == confirm_button_)
parent_->NotifyConfirmedNeverForThisSite();
else
parent_->NotifyUndoNeverForThisSite();
} }
// ManagePasswordsBubbleView::ManageView -------------------------------------- // ManagePasswordsBubbleView::ManageView --------------------------------------
...@@ -417,7 +490,8 @@ ManagePasswordsBubbleView::ManagePasswordsBubbleView( ...@@ -417,7 +490,8 @@ ManagePasswordsBubbleView::ManagePasswordsBubbleView(
BubbleDelegateView(anchor_view, BubbleDelegateView(anchor_view,
anchor_view ? views::BubbleBorder::TOP_RIGHT anchor_view ? views::BubbleBorder::TOP_RIGHT
: views::BubbleBorder::NONE), : views::BubbleBorder::NONE),
anchor_view_(anchor_view) { anchor_view_(anchor_view),
never_save_passwords_(false) {
// Compensate for built-in vertical padding in the anchor view's image. // Compensate for built-in vertical padding in the anchor view's image.
set_anchor_view_insets(gfx::Insets(2, 0, 2, 0)); set_anchor_view_insets(gfx::Insets(2, 0, 2, 0));
set_notify_enter_exit_on_child(true); set_notify_enter_exit_on_child(true);
...@@ -453,12 +527,7 @@ void ManagePasswordsBubbleView::Init() { ...@@ -453,12 +527,7 @@ void ManagePasswordsBubbleView::Init() {
SetLayoutManager(layout); SetLayoutManager(layout);
SetFocusable(true); SetFocusable(true);
if (password_manager::ui::IsPendingState(model()->state())) Refresh();
AddChildView(new PendingView(this));
else if (model()->state() == password_manager::ui::BLACKLIST_STATE)
AddChildView(new BlacklistedView(this));
else
AddChildView(new ManageView(this));
} }
void ManagePasswordsBubbleView::WindowClosing() { void ManagePasswordsBubbleView::WindowClosing() {
...@@ -467,3 +536,38 @@ void ManagePasswordsBubbleView::WindowClosing() { ...@@ -467,3 +536,38 @@ void ManagePasswordsBubbleView::WindowClosing() {
if (manage_passwords_bubble_ == this) if (manage_passwords_bubble_ == this)
manage_passwords_bubble_ = NULL; manage_passwords_bubble_ = NULL;
} }
void ManagePasswordsBubbleView::Refresh() {
RemoveAllChildViews(true);
if (password_manager::ui::IsPendingState(model()->state())) {
if (never_save_passwords_)
AddChildView(new ConfirmNeverView(this));
else
AddChildView(new PendingView(this));
} else if (model()->state() == password_manager::ui::BLACKLIST_STATE) {
AddChildView(new BlacklistedView(this));
} else {
AddChildView(new ManageView(this));
}
GetLayoutManager()->Layout(this);
}
void ManagePasswordsBubbleView::NotifyNeverForThisSiteClicked() {
if (model()->best_matches().empty()) {
// Skip confirmation if there are no existing passwords for this site.
NotifyConfirmedNeverForThisSite();
} else {
never_save_passwords_ = true;
Refresh();
}
}
void ManagePasswordsBubbleView::NotifyConfirmedNeverForThisSite() {
model()->OnNeverForThisSiteClicked();
Close();
}
void ManagePasswordsBubbleView::NotifyUndoNeverForThisSite() {
never_save_passwords_ = false;
Refresh();
}
...@@ -68,6 +68,24 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble, ...@@ -68,6 +68,24 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble,
scoped_ptr<views::Combobox> refuse_combobox_; scoped_ptr<views::Combobox> refuse_combobox_;
}; };
// A view offering the user the ability to undo her decision to never save
// passwords for a particular site.
class ConfirmNeverView : public views::View, public views::ButtonListener {
public:
explicit ConfirmNeverView(ManagePasswordsBubbleView* parent);
virtual ~ConfirmNeverView();
private:
// views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
ManagePasswordsBubbleView* parent_;
views::LabelButton* confirm_button_;
views::LabelButton* undo_button_;
};
// A view offering the user a list of her currently saved credentials // A view offering the user a list of her currently saved credentials
// for the current page, along with a "Manage passwords" link and a // for the current page, along with a "Manage passwords" link and a
// "Done" button. // "Done" button.
...@@ -135,6 +153,22 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble, ...@@ -135,6 +153,22 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble,
// Close the bubble. // Close the bubble.
void Close(); void Close();
// Refreshes the bubble's state: called to display a confirmation screen after
// a user selects "Never for this site", for instance.
void Refresh();
// Called from PendingView if the user clicks on "Never for this site" in
// order to display a confirmation screen.
void NotifyNeverForThisSiteClicked();
// Called from ConfirmNeverView if the user confirms her intention to never
// save passwords, and remove existing passwords, for a site.
void NotifyConfirmedNeverForThisSite();
// Called from ConfirmNeverView if the user clicks on "Undo" in order to
// undo the action and refresh to PendingView.
void NotifyUndoNeverForThisSite();
// views::BubbleDelegateView: // views::BubbleDelegateView:
virtual void Init() OVERRIDE; virtual void Init() OVERRIDE;
virtual void WindowClosing() OVERRIDE; virtual void WindowClosing() OVERRIDE;
...@@ -146,6 +180,10 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble, ...@@ -146,6 +180,10 @@ class ManagePasswordsBubbleView : public ManagePasswordsBubble,
ManagePasswordsIconView* anchor_view_; ManagePasswordsIconView* anchor_view_;
// If true upon destruction, the user has confirmed that she never wants to
// save passwords for a particular site.
bool never_save_passwords_;
DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleView); DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleView);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment