summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-09 11:34:51 +0000
committerbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-09 11:34:51 +0000
commit5ec40cfbe054961db55591c94e46979c4c4d53d7 (patch)
tree9412e0b34a4da5569e5d2c5d06edb4885f9a9d3d /chrome
parentd6d0cf6a3dea6ec00a70781cca4902e133090647 (diff)
downloadchromium_src-5ec40cfbe054961db55591c94e46979c4c4d53d7.zip
chromium_src-5ec40cfbe054961db55591c94e46979c4c4d53d7.tar.gz
chromium_src-5ec40cfbe054961db55591c94e46979c4c4d53d7.tar.bz2
Adds ContentSettingBubbleModel.
Review URL: http://codereview.chromium.org/668075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41021 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/content_setting_bubble_model.cc188
-rw-r--r--chrome/browser/content_setting_bubble_model.h94
-rw-r--r--chrome/browser/content_setting_bubble_model_unittest.cc45
-rw-r--r--chrome/browser/gtk/content_blocked_bubble_gtk.cc234
-rw-r--r--chrome/browser/gtk/content_blocked_bubble_gtk.h55
-rw-r--r--chrome/browser/gtk/location_bar_view_gtk.cc9
-rw-r--r--chrome/browser/gtk/location_bar_view_gtk.h4
-rw-r--r--chrome/browser/views/content_blocked_bubble_contents.cc183
-rw-r--r--chrome/browser/views/content_blocked_bubble_contents.h32
-rw-r--r--chrome/browser/views/location_bar_view.cc16
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi3
12 files changed, 543 insertions, 322 deletions
diff --git a/chrome/browser/content_setting_bubble_model.cc b/chrome/browser/content_setting_bubble_model.cc
new file mode 100644
index 0000000..e361b12
--- /dev/null
+++ b/chrome/browser/content_setting_bubble_model.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/content_setting_bubble_model.h"
+
+#include "app/l10n_util.h"
+#include "chrome/browser/blocked_popup_container.h"
+#include "chrome/browser/host_content_settings_map.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_delegate.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/pref_names.h"
+#include "grit/generated_resources.h"
+#include "net/base/net_util.h"
+
+class ContentSettingTitleAndLinkModel : public ContentSettingBubbleModel {
+ public:
+ ContentSettingTitleAndLinkModel(TabContents* tab_contents, Profile* profile,
+ ContentSettingsType content_type)
+ : ContentSettingBubbleModel(tab_contents, profile, content_type) {
+ SetTitle();
+ SetManageLink();
+ }
+
+ private:
+ void SetTitle() {
+ static const int kTitleIDs[CONTENT_SETTINGS_NUM_TYPES] = {
+ IDS_BLOCKED_COOKIES_TITLE,
+ IDS_BLOCKED_IMAGES_TITLE,
+ IDS_BLOCKED_JAVASCRIPT_TITLE,
+ IDS_BLOCKED_PLUGINS_TITLE,
+ IDS_BLOCKED_POPUPS_TITLE,
+ };
+ set_title(l10n_util::GetStringUTF8(kTitleIDs[content_type()]));
+ }
+
+ void SetManageLink() {
+ static const int kLinkIDs[CONTENT_SETTINGS_NUM_TYPES] = {
+ IDS_BLOCKED_COOKIES_LINK,
+ IDS_BLOCKED_IMAGES_LINK,
+ IDS_BLOCKED_JAVASCRIPT_LINK,
+ IDS_BLOCKED_PLUGINS_LINK,
+ IDS_BLOCKED_POPUPS_LINK,
+ };
+ set_manage_link(l10n_util::GetStringUTF8(kLinkIDs[content_type()]));
+ }
+
+ virtual void OnManageLinkClicked() {
+ if (tab_contents())
+ tab_contents()->delegate()->ShowContentSettingsWindow(content_type());
+ }
+};
+
+class ContentSettingSingleRadioGroup : public ContentSettingTitleAndLinkModel {
+ public:
+ ContentSettingSingleRadioGroup(TabContents* tab_contents, Profile* profile,
+ ContentSettingsType content_type)
+ : ContentSettingTitleAndLinkModel(tab_contents, profile, content_type) {
+ SetRadioGroups();
+ }
+
+ private:
+ void SetRadioGroups() {
+ GURL url = tab_contents()->GetURL();
+ std::wstring display_host_wide;
+ net::AppendFormattedHost(url,
+ profile()->GetPrefs()->GetString(prefs::kAcceptLanguages),
+ &display_host_wide, NULL, NULL);
+ std::string display_host(WideToUTF8(display_host_wide));
+
+ RadioGroup radio_group;
+ radio_group.host = url.host();
+
+ static const int kAllowIDs[CONTENT_SETTINGS_NUM_TYPES] = {
+ 0, // We don't manage cookies here.
+ IDS_BLOCKED_IMAGES_UNBLOCK,
+ IDS_BLOCKED_JAVASCRIPT_UNBLOCK,
+ IDS_BLOCKED_PLUGINS_UNBLOCK,
+ IDS_BLOCKED_POPUPS_UNBLOCK,
+ };
+ std::string radio_allow_label;
+ radio_allow_label = l10n_util::GetStringFUTF8(
+ kAllowIDs[content_type()], UTF8ToUTF16(display_host));
+
+ static const int kBlockIDs[CONTENT_SETTINGS_NUM_TYPES] = {
+ 0, // We don't manage cookies here.
+ IDS_BLOCKED_IMAGES_NO_ACTION,
+ IDS_BLOCKED_JAVASCRIPT_NO_ACTION,
+ IDS_BLOCKED_PLUGINS_NO_ACTION,
+ IDS_BLOCKED_POPUPS_NO_ACTION,
+ };
+ std::string radio_block_label;
+ radio_block_label = l10n_util::GetStringFUTF8(
+ kBlockIDs[content_type()], UTF8ToUTF16(display_host));
+
+ radio_group.radio_items.push_back(radio_allow_label);
+ radio_group.radio_items.push_back(radio_block_label);
+ radio_group.default_item =
+ profile()->GetHostContentSettingsMap()->GetContentSetting(url,
+ content_type()) == CONTENT_SETTING_ALLOW ? 0 : 1;
+ add_radio_group(radio_group);
+ }
+
+ virtual void OnRadioClicked(int radio_group, int radio_index) {
+ profile()->GetHostContentSettingsMap()->SetContentSetting(
+ bubble_content().radio_groups[radio_group].host,
+ content_type(),
+ radio_index == 0 ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+ }
+};
+
+class ContentSettingPopupBubbleModel : public ContentSettingSingleRadioGroup {
+ public:
+ ContentSettingPopupBubbleModel(TabContents* tab_contents, Profile* profile,
+ ContentSettingsType content_type)
+ : ContentSettingSingleRadioGroup(tab_contents, profile, content_type) {
+ SetPopups();
+ }
+
+ private:
+ void SetPopups() {
+ BlockedPopupContainer::BlockedContents blocked_contents;
+ DCHECK(tab_contents()->blocked_popup_container());
+ tab_contents()->blocked_popup_container()->GetBlockedContents(
+ &blocked_contents);
+ for (BlockedPopupContainer::BlockedContents::const_iterator
+ i(blocked_contents.begin()); i != blocked_contents.end(); ++i) {
+ std::string title(UTF16ToUTF8((*i)->GetTitle()));
+ // The popup may not have committed a load yet, in which case it won't
+ // have a URL or title.
+ if (title.empty())
+ title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE);
+ PopupItem popup_item;
+ popup_item.title = title;
+ popup_item.bitmap = (*i)->GetFavIcon();
+ popup_item.tab_contents = (*i);
+ add_popup(popup_item);
+ }
+ }
+
+ virtual void OnPopupClicked(int index) {
+ if (tab_contents() && tab_contents()->blocked_popup_container()) {
+ tab_contents()->blocked_popup_container()->LaunchPopupForContents(
+ bubble_content().popup_items[index].tab_contents);
+ }
+ }
+};
+
+// static
+ContentSettingBubbleModel*
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ TabContents* tab_contents,
+ Profile* profile,
+ ContentSettingsType content_type) {
+ if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) {
+ return new ContentSettingTitleAndLinkModel(tab_contents, profile,
+ content_type);
+ }
+ if (content_type == CONTENT_SETTINGS_TYPE_POPUPS) {
+ return new ContentSettingPopupBubbleModel(tab_contents, profile,
+ content_type);
+ }
+ return new ContentSettingSingleRadioGroup(tab_contents, profile,
+ content_type);
+}
+
+ContentSettingBubbleModel::ContentSettingBubbleModel(
+ TabContents* tab_contents, Profile* profile,
+ ContentSettingsType content_type)
+ : tab_contents_(tab_contents), profile_(profile),
+ content_type_(content_type) {
+ registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_contents));
+}
+
+ContentSettingBubbleModel::~ContentSettingBubbleModel() {
+}
+
+void ContentSettingBubbleModel::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
+ DCHECK(source == Source<TabContents>(tab_contents_));
+ tab_contents_ = NULL;
+}
diff --git a/chrome/browser/content_setting_bubble_model.h b/chrome/browser/content_setting_bubble_model.h
new file mode 100644
index 0000000..dcbafb7
--- /dev/null
+++ b/chrome/browser/content_setting_bubble_model.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CONTENT_SETTING_BUBBLE_MODEL_H_
+#define CHROME_BROWSER_CONTENT_SETTING_BUBBLE_MODEL_H_
+
+#include <string>
+#include <vector>
+
+#include "chrome/common/content_settings.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+class Profile;
+class SkBitmap;
+class TabContents;
+
+// This model provides data for ContentSettingBubble, and also controls
+// the action triggered when the allow / block radio buttons are triggered.
+class ContentSettingBubbleModel : public NotificationObserver {
+ public:
+ virtual ~ContentSettingBubbleModel();
+
+ static ContentSettingBubbleModel* CreateContentSettingBubbleModel(
+ TabContents* tab_contents,
+ Profile* profile,
+ ContentSettingsType content_type);
+
+ ContentSettingsType content_type() const { return content_type_; }
+
+ struct PopupItem {
+ SkBitmap bitmap;
+ std::string title;
+ TabContents* tab_contents;
+ };
+ typedef std::vector<PopupItem> PopupItems;
+
+ typedef std::vector<std::string> RadioItems;
+ struct RadioGroup {
+ std::string host;
+ std::string title;
+ RadioItems radio_items;
+ int default_item;
+ };
+ typedef std::vector<RadioGroup> RadioGroups;
+
+ struct BubbleContent {
+ std::string title;
+ PopupItems popup_items;
+ RadioGroups radio_groups;
+ std::string manage_link;
+ };
+
+ const BubbleContent& bubble_content() const { return bubble_content_; }
+
+ // NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ virtual void OnRadioClicked(int radio_group, int radio_index) {}
+ virtual void OnPopupClicked(int index) {}
+ virtual void OnManageLinkClicked() {}
+
+ protected:
+ ContentSettingBubbleModel(TabContents* tab_contents, Profile* profile,
+ ContentSettingsType content_type);
+
+ TabContents* tab_contents() const { return tab_contents_; }
+ Profile* profile() const { return profile_; }
+
+ void set_title(const std::string& title) { bubble_content_.title = title; }
+ void add_popup(const PopupItem& popup) {
+ bubble_content_.popup_items.push_back(popup);
+ }
+ void add_radio_group(const RadioGroup& radio_group) {
+ bubble_content_.radio_groups.push_back(radio_group);
+ }
+ void set_manage_link(const std::string& link) {
+ bubble_content_.manage_link = link;
+ }
+
+ private:
+ TabContents* tab_contents_;
+ Profile* profile_;
+ ContentSettingsType content_type_;
+ BubbleContent bubble_content_;
+ // A registrar for listening for TAB_CONTENTS_DESTROYED notifications.
+ NotificationRegistrar registrar_;
+};
+
+#endif // CHROME_BROWSER_CONTENT_SETTING_BUBBLE_MODEL_H_
diff --git a/chrome/browser/content_setting_bubble_model_unittest.cc b/chrome/browser/content_setting_bubble_model_unittest.cc
new file mode 100644
index 0000000..d75ceff
--- /dev/null
+++ b/chrome/browser/content_setting_bubble_model_unittest.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/content_setting_bubble_model.h"
+
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/test/test_render_view_host.h"
+#include "chrome/browser/tab_contents/test_tab_contents.h"
+#include "chrome/test/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+typedef RenderViewHostTestHarness ContentSettingBubbleModelTest;
+
+TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
+ TestTabContents tab_contents(profile_.get(), NULL);
+ RenderViewHostDelegate::Resource* render_view_host_delegate = &tab_contents;
+ render_view_host_delegate->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
+
+ scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ &tab_contents, profile_.get(), CONTENT_SETTINGS_TYPE_IMAGES));
+ const ContentSettingBubbleModel::BubbleContent& bubble_content =
+ content_setting_bubble_model->bubble_content();
+ EXPECT_EQ(1U, bubble_content.radio_groups.size());
+ EXPECT_EQ(2U, bubble_content.radio_groups[0].radio_items.size());
+ EXPECT_EQ(0, bubble_content.radio_groups[0].default_item);
+ EXPECT_NE(std::string(), bubble_content.manage_link);
+ EXPECT_NE(std::string(), bubble_content.title);
+}
+
+TEST_F(ContentSettingBubbleModelTest, Cookies) {
+ TestTabContents tab_contents(profile_.get(), NULL);
+ RenderViewHostDelegate::Resource* render_view_host_delegate = &tab_contents;
+ render_view_host_delegate->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
+
+ scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ &tab_contents, profile_.get(), CONTENT_SETTINGS_TYPE_COOKIES));
+ const ContentSettingBubbleModel::BubbleContent& bubble_content =
+ content_setting_bubble_model->bubble_content();
+ EXPECT_EQ(0U, bubble_content.radio_groups.size());
+ EXPECT_NE(std::string(), bubble_content.manage_link);
+ EXPECT_NE(std::string(), bubble_content.title);
+}
diff --git a/chrome/browser/gtk/content_blocked_bubble_gtk.cc b/chrome/browser/gtk/content_blocked_bubble_gtk.cc
index 3bc1873..11bc921 100644
--- a/chrome/browser/gtk/content_blocked_bubble_gtk.cc
+++ b/chrome/browser/gtk/content_blocked_bubble_gtk.cc
@@ -7,6 +7,7 @@
#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "chrome/browser/blocked_popup_container.h"
+#include "chrome/browser/content_setting_bubble_model.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
@@ -23,46 +24,40 @@
// Padding between content and edge of info bubble.
static const int kContentBorder = 7;
-ContentBlockedBubbleGtk::ContentBlockedBubbleGtk(
+ContentSettingBubbleGtk::ContentSettingBubbleGtk(
GtkWindow* toplevel_window,
const gfx::Rect& bounds,
InfoBubbleGtkDelegate* delegate,
- ContentSettingsType content_type,
- const std::string& host,
- const std::wstring& display_host,
+ ContentSettingBubbleModel* content_setting_bubble_model,
Profile* profile,
TabContents* tab_contents)
: toplevel_window_(toplevel_window),
bounds_(bounds),
- content_type_(content_type),
- host_(host),
- display_host_(display_host),
profile_(profile),
tab_contents_(tab_contents),
delegate_(delegate),
- info_bubble_(NULL),
- allow_radio_(NULL),
- block_radio_(NULL) {
+ content_setting_bubble_model_(content_setting_bubble_model),
+ info_bubble_(NULL) {
registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
Source<TabContents>(tab_contents));
BuildBubble();
}
-ContentBlockedBubbleGtk::~ContentBlockedBubbleGtk() {
+ContentSettingBubbleGtk::~ContentSettingBubbleGtk() {
}
-void ContentBlockedBubbleGtk::Close() {
+void ContentSettingBubbleGtk::Close() {
if (info_bubble_)
info_bubble_->Close();
}
-void ContentBlockedBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
+void ContentSettingBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
bool closed_by_escape) {
delegate_->InfoBubbleClosing(info_bubble, closed_by_escape);
delete this;
}
-void ContentBlockedBubbleGtk::Observe(NotificationType type,
+void ContentSettingBubbleGtk::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
@@ -70,42 +65,28 @@ void ContentBlockedBubbleGtk::Observe(NotificationType type,
tab_contents_ = NULL;
}
-void ContentBlockedBubbleGtk::BuildBubble() {
+void ContentSettingBubbleGtk::BuildBubble() {
GtkThemeProvider* theme_provider = GtkThemeProvider::GetFrom(profile_);
GtkWidget* bubble_content = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
gtk_container_set_border_width(GTK_CONTAINER(bubble_content), kContentBorder);
// Add the content label.
- static const int kTitleIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- IDS_BLOCKED_COOKIES_TITLE,
- IDS_BLOCKED_IMAGES_TITLE,
- IDS_BLOCKED_JAVASCRIPT_TITLE,
- IDS_BLOCKED_PLUGINS_TITLE,
- IDS_BLOCKED_POPUPS_TITLE,
- };
- DCHECK_EQ(arraysize(kTitleIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8(
- kTitleIDs[content_type_]).c_str());
+ GtkWidget* label = gtk_label_new(
+ content_setting_bubble_model_->bubble_content().title.c_str());
gtk_box_pack_start(GTK_BOX(bubble_content), label, FALSE, FALSE, 0);
- if (content_type_ == CONTENT_SETTINGS_TYPE_POPUPS) {
- BlockedPopupContainer::BlockedContents blocked_contents;
- DCHECK(tab_contents_);
- DCHECK(tab_contents_->blocked_popup_container());
- tab_contents_->blocked_popup_container()->GetBlockedContents(
- &blocked_contents);
-
- GtkWidget* table = gtk_table_new(blocked_contents.size(), 2, FALSE);
+ if (content_setting_bubble_model_->content_type() ==
+ CONTENT_SETTINGS_TYPE_POPUPS) {
+ const std::vector<ContentSettingBubbleModel::PopupItem>& popup_items =
+ content_setting_bubble_model_->bubble_content().popup_items;
+ GtkWidget* table = gtk_table_new(popup_items.size(), 2, FALSE);
int row = 0;
- for (BlockedPopupContainer::BlockedContents::const_iterator
- i(blocked_contents.begin()); i != blocked_contents.end();
- ++i, ++row) {
- SkBitmap icon = (*i)->GetFavIcon();
+ for (std::vector<ContentSettingBubbleModel::PopupItem>::const_iterator
+ i(popup_items.begin()); i != popup_items.end(); ++i, ++row) {
GtkWidget* image = gtk_image_new();
- if (!icon.empty()) {
- GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
+ if (!i->bitmap.empty()) {
+ GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&i->bitmap);
gtk_image_set_from_pixbuf(GTK_IMAGE(image), icon_pixbuf);
g_object_unref(icon_pixbuf);
@@ -114,7 +95,7 @@ void ContentBlockedBubbleGtk::BuildBubble() {
GtkWidget* event_box = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(event_box), image);
- popup_icons_[event_box] = *i;
+ popup_icons_[event_box] = i -popup_items.begin();
g_signal_connect(event_box, "button_press_event",
G_CALLBACK(OnPopupIconButtonPress), this);
gtk_table_attach(GTK_TABLE(table), event_box, 0, 1, row, row + 1,
@@ -122,15 +103,8 @@ void ContentBlockedBubbleGtk::BuildBubble() {
gtk_util::kControlSpacing / 2);
}
- string16 title((*i)->GetTitle());
- // The popup may not have committed a load yet, in which case it won't
- // have a URL or title.
- if (title.empty())
- title = l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE);
-
- GtkWidget* button =
- gtk_chrome_link_button_new(UTF16ToUTF8(title).c_str());
- popup_links_[button] = *i;
+ GtkWidget* button = gtk_chrome_link_button_new(i->title.c_str());
+ popup_links_[button] = i -popup_items.begin();
g_signal_connect(button, "clicked", G_CALLBACK(OnPopupLinkClicked),
this);
gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1,
@@ -141,67 +115,44 @@ void ContentBlockedBubbleGtk::BuildBubble() {
gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0);
}
- if (content_type_ != CONTENT_SETTINGS_TYPE_COOKIES) {
- static const int kAllowIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- 0, // Not displayed for cookies
- IDS_BLOCKED_IMAGES_UNBLOCK,
- IDS_BLOCKED_JAVASCRIPT_UNBLOCK,
- IDS_BLOCKED_PLUGINS_UNBLOCK,
- IDS_BLOCKED_POPUPS_UNBLOCK,
- };
- DCHECK_EQ(arraysize(kAllowIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- allow_radio_ = gtk_radio_button_new_with_label(
- NULL,
- l10n_util::GetStringFUTF8(kAllowIDs[content_type_],
- WideToUTF16Hack(display_host_)).c_str());
- gtk_box_pack_start(GTK_BOX(bubble_content), allow_radio_, FALSE,
- FALSE, 0);
-
- static const int kBlockIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- 0, // Not displayed for cookies
- IDS_BLOCKED_IMAGES_NO_ACTION,
- IDS_BLOCKED_JAVASCRIPT_NO_ACTION,
- IDS_BLOCKED_PLUGINS_NO_ACTION,
- IDS_BLOCKED_POPUPS_NO_ACTION,
- };
- DCHECK_EQ(arraysize(kBlockIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- block_radio_ = gtk_radio_button_new_with_label_from_widget(
- GTK_RADIO_BUTTON(allow_radio_),
- l10n_util::GetStringUTF8(kBlockIDs[content_type_]).c_str());
- gtk_box_pack_start(GTK_BOX(bubble_content), block_radio_, FALSE,
- FALSE, 0);
-
- // We must set the default value before we attach the signal handlers or
- // pain occurs.
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
- (profile_->GetHostContentSettingsMap()->GetContentSetting(host_,
- content_type_) == CONTENT_SETTING_ALLOW) ?
- allow_radio_ : block_radio_), TRUE);
-
- g_signal_connect(allow_radio_, "toggled",
- G_CALLBACK(OnAllowBlockToggled), this);
- g_signal_connect(block_radio_, "toggled",
- G_CALLBACK(OnAllowBlockToggled), this);
+ if (content_setting_bubble_model_->content_type() !=
+ CONTENT_SETTINGS_TYPE_COOKIES) {
+ const ContentSettingBubbleModel::RadioGroups& radio_groups =
+ content_setting_bubble_model_->bubble_content().radio_groups;
+ for (ContentSettingBubbleModel::RadioGroups::const_iterator i =
+ radio_groups.begin(); i != radio_groups.end(); ++i) {
+ const ContentSettingBubbleModel::RadioItems& radio_items = i->radio_items;
+ RadioGroupGtk radio_group_gtk;
+ for (ContentSettingBubbleModel::RadioItems::const_iterator j =
+ radio_items.begin(); j != radio_items.end(); ++j) {
+ GtkWidget* radio =
+ radio_group_gtk.empty() ?
+ gtk_radio_button_new_with_label(NULL, j->c_str()) :
+ gtk_radio_button_new_with_label_from_widget(
+ GTK_RADIO_BUTTON(radio_group_gtk[0]),
+ j->c_str());
+ gtk_box_pack_start(GTK_BOX(bubble_content), radio, FALSE, FALSE, 0);
+ if (j - radio_items.begin() == i->default_item) {
+ // We must set the default value before we attach the signal handlers
+ // or pain occurs.
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
+ }
+ radio_group_gtk.push_back(radio);
+ }
+ for (std::vector<GtkWidget*>::const_iterator j = radio_group_gtk.begin();
+ j != radio_group_gtk.end(); ++j) {
+ g_signal_connect(*j, "toggled", G_CALLBACK(OnRadioToggled), this);
+ }
+ radio_groups_gtk_.push_back(radio_group_gtk);
+ gtk_box_pack_start(GTK_BOX(bubble_content), gtk_hseparator_new(), FALSE,
+ FALSE, 0);
+ }
}
- gtk_box_pack_start(GTK_BOX(bubble_content), gtk_hseparator_new(), FALSE,
- FALSE, 0);
-
GtkWidget* bottom_box = gtk_hbox_new(FALSE, 0);
- static const int kLinkIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- IDS_BLOCKED_COOKIES_LINK,
- IDS_BLOCKED_IMAGES_LINK,
- IDS_BLOCKED_JAVASCRIPT_LINK,
- IDS_BLOCKED_PLUGINS_LINK,
- IDS_BLOCKED_POPUPS_LINK,
- };
- DCHECK_EQ(arraysize(kLinkIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- GtkWidget* manage_link = gtk_chrome_link_button_new(l10n_util::GetStringUTF8(
- kLinkIDs[content_type_]).c_str());
+ GtkWidget* manage_link = gtk_chrome_link_button_new(
+ content_setting_bubble_model_->bubble_content().manage_link.c_str());
g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClicked),
this);
gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0);
@@ -227,65 +178,62 @@ void ContentBlockedBubbleGtk::BuildBubble() {
this);
}
-void ContentBlockedBubbleGtk::LaunchPopup(TabContents* popup) {
- if (tab_contents_ && tab_contents_->blocked_popup_container()) {
- tab_contents_->blocked_popup_container()->LaunchPopupForContents(popup);
-
- // The views interface implicitly closes because of the launching of a new
- // window; we need to do that explicitly.
- Close();
- }
-}
-
// static
-void ContentBlockedBubbleGtk::OnPopupIconButtonPress(
+void ContentSettingBubbleGtk::OnPopupIconButtonPress(
GtkWidget* icon_event_box,
GdkEventButton* event,
- ContentBlockedBubbleGtk* bubble) {
+ ContentSettingBubbleGtk* bubble) {
PopupMap::iterator i(bubble->popup_icons_.find(icon_event_box));
DCHECK(i != bubble->popup_icons_.end());
- bubble->LaunchPopup(i->second);
+ bubble->content_setting_bubble_model_->OnPopupClicked(i->second);
+ // The views interface implicitly closes because of the launching of a new
+ // window; we need to do that explicitly.
+ bubble->Close();
+
}
// static
-void ContentBlockedBubbleGtk::OnPopupLinkClicked(
+void ContentSettingBubbleGtk::OnPopupLinkClicked(
GtkWidget* button,
- ContentBlockedBubbleGtk* bubble) {
+ ContentSettingBubbleGtk* bubble) {
PopupMap::iterator i(bubble->popup_links_.find(button));
DCHECK(i != bubble->popup_links_.end());
- bubble->LaunchPopup(i->second);
+ bubble->content_setting_bubble_model_->OnPopupClicked(i->second);
+ // The views interface implicitly closes because of the launching of a new
+ // window; we need to do that explicitly.
+ bubble->Close();
}
// static
-void ContentBlockedBubbleGtk::OnAllowBlockToggled(
+void ContentSettingBubbleGtk::OnRadioToggled(
GtkWidget* widget,
- ContentBlockedBubbleGtk* bubble) {
- DCHECK((widget == bubble->allow_radio_) || (widget == bubble->block_radio_));
- bubble->profile_->GetHostContentSettingsMap()->SetContentSetting(
- bubble->host_,
- bubble->content_type_,
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bubble->allow_radio_)) ?
- CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+ ContentSettingBubbleGtk* bubble) {
+ for (std::vector<RadioGroupGtk>::const_iterator i =
+ bubble->radio_groups_gtk_.begin();
+ i != bubble->radio_groups_gtk_.end(); ++i) {
+ for (RadioGroupGtk::const_iterator j = i->begin(); j != i->end(); j++) {
+ if (widget == *j) {
+ bubble->content_setting_bubble_model_->OnRadioClicked(
+ i - bubble->radio_groups_gtk_.begin(),
+ j - i->begin());
+ return;
+ }
+ }
+ }
+ NOTREACHED() << "unknown radio toggled";
}
// static
-void ContentBlockedBubbleGtk::OnCloseButtonClicked(
+void ContentSettingBubbleGtk::OnCloseButtonClicked(
GtkButton *button,
- ContentBlockedBubbleGtk* bubble) {
+ ContentSettingBubbleGtk* bubble) {
bubble->Close();
}
// static
-void ContentBlockedBubbleGtk::OnManageLinkClicked(
+void ContentSettingBubbleGtk::OnManageLinkClicked(
GtkButton* button,
- ContentBlockedBubbleGtk* bubble) {
- if (bubble->tab_contents_) {
- bubble->tab_contents_->delegate()->ShowContentSettingsWindow(
- bubble->content_type_);
- } else {
- ContentSettingsWindowGtk::Show(NULL, bubble->content_type_,
- bubble->profile_);
- }
-
+ ContentSettingBubbleGtk* bubble) {
+ bubble->content_setting_bubble_model_->OnManageLinkClicked();
bubble->Close();
}
diff --git a/chrome/browser/gtk/content_blocked_bubble_gtk.h b/chrome/browser/gtk/content_blocked_bubble_gtk.h
index d201574..7939e8a 100644
--- a/chrome/browser/gtk/content_blocked_bubble_gtk.h
+++ b/chrome/browser/gtk/content_blocked_bubble_gtk.h
@@ -8,35 +8,36 @@
#include <map>
#include <string>
+#include "base/scoped_ptr.h"
#include "chrome/browser/gtk/info_bubble_gtk.h"
#include "chrome/common/content_settings_types.h"
#include "chrome/common/notification_registrar.h"
+class ContentSettingBubbleModel;
class Profile;
class TabContents;
-// ContentBlockedBubbleGtk is used when the user turns on different kinds of
+// ContentSettingBubbleGtk is used when the user turns on different kinds of
// content blocking (e.g. "block images"). An icon appears in the location bar,
// and when clicked, an instance of this class is created specialized for the
// type of content being blocked.
-class ContentBlockedBubbleGtk : public InfoBubbleGtkDelegate,
+// TODO(bulach): rename this file.
+class ContentSettingBubbleGtk : public InfoBubbleGtkDelegate,
public NotificationObserver {
public:
- ContentBlockedBubbleGtk(GtkWindow* toplevel_window,
- const gfx::Rect& bounds,
- InfoBubbleGtkDelegate* delegate,
- ContentSettingsType content_type,
- const std::string& host,
- const std::wstring& display_host,
- Profile* profile,
- TabContents* tab_contents);
- virtual ~ContentBlockedBubbleGtk();
+ ContentSettingBubbleGtk(
+ GtkWindow* toplevel_window,
+ const gfx::Rect& bounds,
+ InfoBubbleGtkDelegate* delegate,
+ ContentSettingBubbleModel* content_setting_bubble_model,
+ Profile* profile, TabContents* tab_contents);
+ virtual ~ContentSettingBubbleGtk();
// Dismisses the infobubble.
void Close();
private:
- typedef std::map<GtkWidget*, TabContents*> PopupMap;
+ typedef std::map<GtkWidget*, int> PopupMap;
// InfoBubbleGtkDelegate:
virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble,
@@ -50,21 +51,18 @@ class ContentBlockedBubbleGtk : public InfoBubbleGtkDelegate,
// Builds the info bubble and all the widgets that it displays.
void BuildBubble();
- // Launches a popup from a click on a widget.
- void LaunchPopup(TabContents* popup);
-
// Widget callback methods.
static void OnPopupIconButtonPress(GtkWidget* icon,
GdkEventButton* event,
- ContentBlockedBubbleGtk* bubble);
+ ContentSettingBubbleGtk* bubble);
static void OnPopupLinkClicked(GtkWidget* button,
- ContentBlockedBubbleGtk* bubble);
- static void OnAllowBlockToggled(GtkWidget* widget,
- ContentBlockedBubbleGtk* bubble);
+ ContentSettingBubbleGtk* bubble);
+ static void OnRadioToggled(GtkWidget* widget,
+ ContentSettingBubbleGtk* bubble);
static void OnCloseButtonClicked(GtkButton *button,
- ContentBlockedBubbleGtk* bubble);
+ ContentSettingBubbleGtk* bubble);
static void OnManageLinkClicked(GtkButton* button,
- ContentBlockedBubbleGtk* bubble);
+ ContentSettingBubbleGtk* bubble);
// A reference to the toplevel browser window, which we pass to the
// InfoBubbleGtk implementation so it can tell the WM that it's a subwindow.
@@ -73,13 +71,6 @@ class ContentBlockedBubbleGtk : public InfoBubbleGtkDelegate,
// Positioning information for the info bubble.
gfx::Rect bounds_;
- // The type of content handled by this view.
- ContentSettingsType content_type_;
-
- // The hostname affected.
- std::string host_;
- std::wstring display_host_;
-
// The active profile.
Profile* profile_;
@@ -92,14 +83,18 @@ class ContentBlockedBubbleGtk : public InfoBubbleGtkDelegate,
// Pass on delegate messages to this.
InfoBubbleGtkDelegate* delegate_;
+ // Provides data for this bubble.
+ scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model_;
+
// The info bubble.
InfoBubbleGtk* info_bubble_;
// Stored controls so we can figure out what was clicked.
PopupMap popup_links_;
PopupMap popup_icons_;
- GtkWidget* allow_radio_;
- GtkWidget* block_radio_;
+
+ typedef std::vector<GtkWidget*> RadioGroupGtk;
+ std::vector<RadioGroupGtk> radio_groups_gtk_;
};
#endif // CHROME_BROWSER_GTK_CONTENT_BLOCKED_BUBBLE_GTK_H_
diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc
index ed0cda4..9e2cb0a 100644
--- a/chrome/browser/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/gtk/location_bar_view_gtk.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/command_updater.h"
+#include "chrome/browser/content_setting_bubble_model.h"
#include "chrome/browser/content_setting_image_model.h"
#include "chrome/browser/extensions/extension_accessibility_api_constants.h"
#include "chrome/browser/extensions/extension_action_context_menu_model.h"
@@ -1016,10 +1017,12 @@ gboolean LocationBarViewGtk::ContentSettingImageViewGtk::OnButtonPressed(
GtkWindow* toplevel = GTK_WINDOW(gtk_widget_get_toplevel(sender));
- info_bubble_ = new ContentBlockedBubbleGtk(
+ info_bubble_ = new ContentSettingBubbleGtk(
toplevel, bounds, this,
- content_setting_image_model_->get_content_settings_type(), url.host(),
- display_host, profile_, tab_contents);
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ tab_contents, profile_,
+ content_setting_image_model_->get_content_settings_type()),
+ profile_, tab_contents);
return TRUE;
}
diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h
index c0da0c7..1da0e7a 100644
--- a/chrome/browser/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/gtk/location_bar_view_gtk.h
@@ -31,8 +31,8 @@ class AutocompleteEditViewGtk;
class BubblePositioner;
class Browser;
class CommandUpdater;
-class ContentBlockedBubbleGtk;
class ContentSettingImageModel;
+class ContentSettingBubbleGtk;
class ExtensionAction;
class ExtensionActionContextMenuModel;
class GtkThemeProvider;
@@ -166,7 +166,7 @@ class LocationBarViewGtk : public AutocompleteEditController,
Profile* profile_;
// The currently shown info bubble if any.
- ContentBlockedBubbleGtk* info_bubble_;
+ ContentSettingBubbleGtk* info_bubble_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingImageViewGtk);
};
diff --git a/chrome/browser/views/content_blocked_bubble_contents.cc b/chrome/browser/views/content_blocked_bubble_contents.cc
index a44311c..e9be34f 100644
--- a/chrome/browser/views/content_blocked_bubble_contents.cc
+++ b/chrome/browser/views/content_blocked_bubble_contents.cc
@@ -10,6 +10,7 @@
#include "app/l10n_util.h"
#include "chrome/browser/blocked_popup_container.h"
+#include "chrome/browser/content_setting_bubble_model.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -26,10 +27,10 @@
#include "views/grid_layout.h"
#include "views/standard_layout.h"
-class ContentBlockedBubbleContents::Favicon : public views::ImageView {
+class ContentSettingBubbleContents::Favicon : public views::ImageView {
public:
Favicon(const SkBitmap& image,
- ContentBlockedBubbleContents* parent,
+ ContentSettingBubbleContents* parent,
views::Link* link);
virtual ~Favicon();
@@ -45,32 +46,32 @@ class ContentBlockedBubbleContents::Favicon : public views::ImageView {
views::Event::EventType event_type,
const gfx::Point& p);
- ContentBlockedBubbleContents* parent_;
+ ContentSettingBubbleContents* parent_;
views::Link* link_;
};
#if defined(OS_WIN)
-HCURSOR ContentBlockedBubbleContents::Favicon::g_hand_cursor = NULL;
+HCURSOR ContentSettingBubbleContents::Favicon::g_hand_cursor = NULL;
#endif
-ContentBlockedBubbleContents::Favicon::Favicon(
+ContentSettingBubbleContents::Favicon::Favicon(
const SkBitmap& image,
- ContentBlockedBubbleContents* parent,
+ ContentSettingBubbleContents* parent,
views::Link* link)
: parent_(parent),
link_(link) {
SetImage(image);
}
-ContentBlockedBubbleContents::Favicon::~Favicon() {
+ContentSettingBubbleContents::Favicon::~Favicon() {
}
-bool ContentBlockedBubbleContents::Favicon::OnMousePressed(
+bool ContentSettingBubbleContents::Favicon::OnMousePressed(
const views::MouseEvent& event) {
return event.IsLeftMouseButton() || event.IsMiddleMouseButton();
}
-void ContentBlockedBubbleContents::Favicon::OnMouseReleased(
+void ContentSettingBubbleContents::Favicon::OnMouseReleased(
const views::MouseEvent& event,
bool canceled) {
if (!canceled &&
@@ -79,7 +80,7 @@ void ContentBlockedBubbleContents::Favicon::OnMouseReleased(
parent_->LinkActivated(link_, event.GetFlags());
}
-gfx::NativeCursor ContentBlockedBubbleContents::Favicon::GetCursorForPoint(
+gfx::NativeCursor ContentSettingBubbleContents::Favicon::GetCursorForPoint(
views::Event::EventType event_type,
const gfx::Point& p) {
#if defined(OS_WIN)
@@ -91,55 +92,54 @@ gfx::NativeCursor ContentBlockedBubbleContents::Favicon::GetCursorForPoint(
#endif
}
-ContentBlockedBubbleContents::ContentBlockedBubbleContents(
- ContentSettingsType content_type,
- const std::string& host,
- const std::wstring& display_host,
+ContentSettingBubbleContents::ContentSettingBubbleContents(
+ ContentSettingBubbleModel* content_setting_bubble_model,
Profile* profile,
TabContents* tab_contents)
- : content_type_(content_type),
- host_(host),
- display_host_(display_host),
+ : content_setting_bubble_model_(content_setting_bubble_model),
profile_(profile),
tab_contents_(tab_contents),
info_bubble_(NULL),
- allow_radio_(NULL),
- block_radio_(NULL),
close_button_(NULL),
manage_link_(NULL) {
registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
Source<TabContents>(tab_contents));
}
-ContentBlockedBubbleContents::~ContentBlockedBubbleContents() {
+ContentSettingBubbleContents::~ContentSettingBubbleContents() {
}
-void ContentBlockedBubbleContents::ViewHierarchyChanged(bool is_add,
+void ContentSettingBubbleContents::ViewHierarchyChanged(bool is_add,
View* parent,
View* child) {
if (is_add && (child == this))
InitControlLayout();
}
-void ContentBlockedBubbleContents::ButtonPressed(views::Button* sender,
+void ContentSettingBubbleContents::ButtonPressed(views::Button* sender,
const views::Event& event) {
if (sender == close_button_) {
info_bubble_->Close(); // CAREFUL: This deletes us.
return;
}
- DCHECK((sender == allow_radio_) || (sender == block_radio_));
- profile_->GetHostContentSettingsMap()->SetContentSetting(host_, content_type_,
- allow_radio_->checked() ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+ for (std::vector<RadioGroup>::const_iterator i = radio_groups_.begin();
+ i != radio_groups_.end(); ++i) {
+ for (RadioGroup::const_iterator j = i->begin(); j != i->end(); ++j) {
+ if (sender == *j) {
+ content_setting_bubble_model_->OnRadioClicked(
+ i - radio_groups_.begin(), j - i->begin());
+ return;
+ }
+ }
+ }
+ NOTREACHED() << "unknown radio";
}
-void ContentBlockedBubbleContents::LinkActivated(views::Link* source,
+void ContentSettingBubbleContents::LinkActivated(views::Link* source,
int event_flags) {
if (source == manage_link_) {
- if (tab_contents_)
- tab_contents_->delegate()->ShowContentSettingsWindow(content_type_);
- else
- browser::ShowContentSettingsWindow(NULL, content_type_, profile_);
+ content_setting_bubble_model_->OnManageLinkClicked();
// CAREFUL: Showing the settings window activates it, which deactivates the
// info bubble, which causes it to close, which deletes us.
return;
@@ -147,11 +147,10 @@ void ContentBlockedBubbleContents::LinkActivated(views::Link* source,
PopupLinks::const_iterator i(popup_links_.find(source));
DCHECK(i != popup_links_.end());
- if (tab_contents_ && tab_contents_->blocked_popup_container())
- tab_contents_->blocked_popup_container()->LaunchPopupForContents(i->second);
+ content_setting_bubble_model_->OnPopupClicked(i->second);
}
-void ContentBlockedBubbleContents::Observe(NotificationType type,
+void ContentSettingBubbleContents::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
@@ -159,7 +158,7 @@ void ContentBlockedBubbleContents::Observe(NotificationType type,
tab_contents_ = NULL;
}
-void ContentBlockedBubbleContents::InitControlLayout() {
+void ContentSettingBubbleContents::InitControlLayout() {
using views::GridLayout;
GridLayout* layout = new views::GridLayout(this);
@@ -170,23 +169,17 @@ void ContentBlockedBubbleContents::InitControlLayout() {
column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
GridLayout::USE_PREF, 0, 0);
- static const int kTitleIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- IDS_BLOCKED_COOKIES_TITLE,
- IDS_BLOCKED_IMAGES_TITLE,
- IDS_BLOCKED_JAVASCRIPT_TITLE,
- IDS_BLOCKED_PLUGINS_TITLE,
- IDS_BLOCKED_POPUPS_TITLE,
- };
- DCHECK_EQ(arraysize(kTitleIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- views::Label* title_label =
- new views::Label(l10n_util::GetString(kTitleIDs[content_type_]));
+ const ContentSettingBubbleModel::BubbleContent& bubble_content =
+ content_setting_bubble_model_->bubble_content();
+ views::Label* title_label = new views::Label(UTF8ToWide(
+ bubble_content.title));
layout->StartRow(0, single_column_set_id);
layout->AddView(title_label);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- if (content_type_ == CONTENT_SETTINGS_TYPE_POPUPS) {
+ if (content_setting_bubble_model_->content_type() ==
+ CONTENT_SETTINGS_TYPE_POPUPS) {
const int popup_column_set_id = 2;
views::ColumnSet* popup_column_set =
layout->AddColumnSet(popup_column_set_id);
@@ -196,26 +189,17 @@ void ContentBlockedBubbleContents::InitControlLayout() {
popup_column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
GridLayout::USE_PREF, 0, 0);
- BlockedPopupContainer::BlockedContents blocked_contents;
- DCHECK(tab_contents_->blocked_popup_container());
- tab_contents_->blocked_popup_container()->GetBlockedContents(
- &blocked_contents);
- for (BlockedPopupContainer::BlockedContents::const_iterator
- i(blocked_contents.begin()); i != blocked_contents.end(); ++i) {
- string16 title((*i)->GetTitle());
- // The popup may not have committed a load yet, in which case it won't
- // have a URL or title.
- if (title.empty())
- title = l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE);
-
- if (i != blocked_contents.begin())
+ for (std::vector<ContentSettingBubbleModel::PopupItem>::const_iterator
+ i(bubble_content.popup_items.begin());
+ i != bubble_content.popup_items.end(); ++i) {
+ if (i != bubble_content.popup_items.begin())
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, popup_column_set_id);
- views::Link* link = new views::Link(UTF16ToWideHack(title));
+ views::Link* link = new views::Link(UTF8ToWide(i->title));
link->SetController(this);
- popup_links_[link] = *i;
- layout->AddView(new Favicon((*i)->GetFavIcon(), this, link));
+ popup_links_[link] = i - bubble_content.popup_items.begin();
+ layout->AddView(new Favicon((*i).bitmap, this, link));
layout->AddView(link);
}
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
@@ -226,54 +210,30 @@ void ContentBlockedBubbleContents::InitControlLayout() {
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
- if (content_type_ != CONTENT_SETTINGS_TYPE_COOKIES) {
- static const int kAllowIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- 0, // Not displayed for cookies
- IDS_BLOCKED_IMAGES_UNBLOCK,
- IDS_BLOCKED_JAVASCRIPT_UNBLOCK,
- IDS_BLOCKED_PLUGINS_UNBLOCK,
- IDS_BLOCKED_POPUPS_UNBLOCK,
- };
- DCHECK_EQ(arraysize(kAllowIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- const int radio_button_group = 0;
- allow_radio_ = new views::RadioButton(
- l10n_util::GetStringF(kAllowIDs[content_type_], display_host_),
- radio_button_group);
- allow_radio_->set_listener(this);
-
- static const int kBlockIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- 0, // Not displayed for cookies
- IDS_BLOCKED_IMAGES_NO_ACTION,
- IDS_BLOCKED_JAVASCRIPT_NO_ACTION,
- IDS_BLOCKED_PLUGINS_NO_ACTION,
- IDS_BLOCKED_POPUPS_NO_ACTION,
- };
- DCHECK_EQ(arraysize(kBlockIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- block_radio_ = new views::RadioButton(
- l10n_util::GetString(kBlockIDs[content_type_]), radio_button_group);
- block_radio_->set_listener(this);
-
- layout->StartRow(0, single_column_set_id);
- layout->AddView(allow_radio_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- layout->StartRow(0, single_column_set_id);
- layout->AddView(block_radio_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- // Now that the buttons have been added to the view hierarchy, it's safe to
- // call SetChecked() on them.
- if (profile_->GetHostContentSettingsMap()->GetContentSetting(host_,
- content_type_) == CONTENT_SETTING_ALLOW)
- allow_radio_->SetChecked(true);
- else
- block_radio_->SetChecked(true);
-
+ const ContentSettingBubbleModel::RadioGroups& radio_groups =
+ content_setting_bubble_model_->bubble_content().radio_groups;
+ for (ContentSettingBubbleModel::RadioGroups::const_iterator i =
+ radio_groups.begin(); i != radio_groups.end(); ++i) {
+ const ContentSettingBubbleModel::RadioItems& radio_items = i->radio_items;
+ RadioGroup radio_group;
+ for (ContentSettingBubbleModel::RadioItems::const_iterator j =
+ radio_items.begin(); j != radio_items.end(); ++j) {
+ views::RadioButton* radio = new views::RadioButton(
+ UTF8ToWide(*j), i - radio_groups.begin());
+ radio->set_listener(this);
+ radio_group.push_back(radio);
+ layout->StartRow(0, single_column_set_id);
+ layout->AddView(radio);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ }
+ radio_groups_.push_back(radio_group);
views::Separator* separator = new views::Separator;
layout->StartRow(0, single_column_set_id);
layout->AddView(separator, 1, 1, GridLayout::FILL, GridLayout::FILL);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ // Now that the buttons have been added to the view hierarchy, it's safe
+ // to call SetChecked() on them.
+ radio_group[i->default_item]->SetChecked(true);
}
const int double_column_set_id = 1;
@@ -285,16 +245,7 @@ void ContentBlockedBubbleContents::InitControlLayout() {
double_column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
GridLayout::USE_PREF, 0, 0);
- static const int kLinkIDs[CONTENT_SETTINGS_NUM_TYPES] = {
- IDS_BLOCKED_COOKIES_LINK,
- IDS_BLOCKED_IMAGES_LINK,
- IDS_BLOCKED_JAVASCRIPT_LINK,
- IDS_BLOCKED_PLUGINS_LINK,
- IDS_BLOCKED_POPUPS_LINK,
- };
- DCHECK_EQ(arraysize(kLinkIDs),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- manage_link_ = new views::Link(l10n_util::GetString(kLinkIDs[content_type_]));
+ manage_link_ = new views::Link(UTF8ToWide(bubble_content.manage_link));
manage_link_->SetController(this);
layout->StartRow(0, double_column_set_id);
diff --git a/chrome/browser/views/content_blocked_bubble_contents.h b/chrome/browser/views/content_blocked_bubble_contents.h
index d4781c4..b27516f 100644
--- a/chrome/browser/views/content_blocked_bubble_contents.h
+++ b/chrome/browser/views/content_blocked_bubble_contents.h
@@ -13,7 +13,7 @@
#include "views/controls/button/button.h"
#include "views/controls/link.h"
-// ContentBlockedBubbleContents is used when the user turns on different kinds
+// ContentSettingBubbleContents is used when the user turns on different kinds
// of content blocking (e.g. "block images"). When viewing a page with blocked
// content, icons appear in the omnibox corresponding to the content types that
// were blocked, and the user can click one to get a bubble hosting a few
@@ -23,6 +23,7 @@
// get to a more comprehensive settings management dialog. A few types have
// more or fewer controls than this.
+class ContentSettingBubbleModel;
class InfoBubble;
class Profile;
class TabContents;
@@ -32,17 +33,16 @@ class NativeButton;
class RadioButton;
}
-class ContentBlockedBubbleContents : public views::View,
+// TODO(bulach): rename this file.
+class ContentSettingBubbleContents : public views::View,
public views::ButtonListener,
public views::LinkController,
public NotificationObserver {
public:
- ContentBlockedBubbleContents(ContentSettingsType content_type,
- const std::string& host,
- const std::wstring& display_host,
- Profile* profile,
- TabContents* tab_contents);
- virtual ~ContentBlockedBubbleContents();
+ ContentSettingBubbleContents(
+ ContentSettingBubbleModel* content_setting_bubble_model,
+ Profile* profile, TabContents* tab_contents);
+ virtual ~ContentSettingBubbleContents();
// Sets |info_bubble_|, so we can close the bubble if needed. The caller owns
// the bubble and must keep it alive.
@@ -51,7 +51,7 @@ class ContentBlockedBubbleContents : public views::View,
private:
class Favicon;
- typedef std::map<views::Link*, TabContents*> PopupLinks;
+ typedef std::map<views::Link*, int> PopupLinks;
// Overridden from views::View:
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
@@ -70,12 +70,8 @@ class ContentBlockedBubbleContents : public views::View,
// Creates the child views.
void InitControlLayout();
- // The type of content handled by this view.
- ContentSettingsType content_type_;
-
- // The hostname affected.
- std::string host_;
- std::wstring display_host_;
+ // Provides data for this bubble.
+ scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model_;
// The active profile.
Profile* profile_;
@@ -92,12 +88,12 @@ class ContentBlockedBubbleContents : public views::View,
// Some of our controls, so we can tell what's been clicked when we get a
// message.
PopupLinks popup_links_;
- views::RadioButton* allow_radio_;
- views::RadioButton* block_radio_;
+ typedef std::vector<views::RadioButton*> RadioGroup;
+ std::vector<RadioGroup> radio_groups_;
views::NativeButton* close_button_;
views::Link* manage_link_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(ContentBlockedBubbleContents);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingBubbleContents);
};
#endif // CHROME_BROWSER_VIEWS_CONTENT_BLOCKED_BUBBLE_CONTENTS_H_
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index 23c439b..b1c8d5b 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/bubble_positioner.h"
#include "chrome/browser/command_updater.h"
+#include "chrome/browser/content_setting_bubble_model.h"
#include "chrome/browser/content_setting_image_model.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extensions_service.h"
@@ -1383,15 +1384,12 @@ bool LocationBarView::ContentSettingImageView::OnMousePressed(
TabContents* tab_contents = parent_->GetTabContents();
if (!tab_contents)
return true;
- GURL url = tab_contents->GetURL();
- std::wstring display_host;
- net::AppendFormattedHost(url,
- profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), &display_host,
- NULL, NULL);
- ContentBlockedBubbleContents* bubble_contents =
- new ContentBlockedBubbleContents(
- content_setting_image_model_->get_content_settings_type(), url.host(),
- display_host, profile_, tab_contents);
+ ContentSettingBubbleContents* bubble_contents =
+ new ContentSettingBubbleContents(
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ tab_contents, profile_,
+ content_setting_image_model_->get_content_settings_type()),
+ profile_, tab_contents);
DCHECK(!info_bubble_);
info_bubble_ = InfoBubble::Show(GetWindow(), bounds, bubble_contents, this);
bubble_contents->set_info_bubble(info_bubble_);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index e3832f0..dceec65 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -751,6 +751,8 @@
'browser/command_updater.h',
'browser/content_exceptions_table_model.cc',
'browser/content_exceptions_table_model.h',
+ 'browser/content_setting_bubble_model.cc',
+ 'browser/content_setting_bubble_model.h',
'browser/content_setting_combo_model.cc',
'browser/content_setting_combo_model.h',
'browser/content_setting_image_model.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index fae75d3..cec0b93 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -567,7 +567,8 @@
'browser/browser_theme_pack_unittest.cc',
'browser/browser_theme_provider_unittest.cc',
'browser/browser_unittest.cc',
- 'browser/content_setting_image_model_unittest.cc',
+ 'browser/content_setting_bubble_model_unittest.cc',
+ 'browser/content_setting_image_model_unittest.cc',
'browser/chrome_browser_application_mac_unittest.mm',
'browser/debugger/devtools_remote_message_unittest.cc',
'browser/debugger/devtools_remote_listen_socket_unittest.cc',