diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-03 08:22:21 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-03 08:22:21 +0000 |
commit | 97c5c596e4b649651fbef56875e125c06acb0f90 (patch) | |
tree | 3acba85143369eacd72006d383e5e198a59f9c7a /chrome/browser | |
parent | 7a13e7926699ad5d03f2d6e121b7bdb68ca05680 (diff) | |
download | chromium_src-97c5c596e4b649651fbef56875e125c06acb0f90.zip chromium_src-97c5c596e4b649651fbef56875e125c06acb0f90.tar.gz chromium_src-97c5c596e4b649651fbef56875e125c06acb0f90.tar.bz2 |
Add "Load all plugins on this page" button to blocked plugins bubble if click-to-play is enabled.
Screenshot: http://imgur.com/ZKsQB.png
XIB changes: Add a rounded rect button hooked up to |loadAllPlugins:| in the File's Owner and referenced by its |loadAllPluginsButton_| outlet, wrapped in a GTMWidthBasedTweaker.
BUG=49677
TEST=ContentSettingBubbleModelTest.*
Review URL: http://codereview.chromium.org/3015036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54720 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
13 files changed, 189 insertions, 7 deletions
diff --git a/chrome/browser/cocoa/content_blocked_bubble_controller.h b/chrome/browser/cocoa/content_blocked_bubble_controller.h index 74b23ce..56f2313 100644 --- a/chrome/browser/cocoa/content_blocked_bubble_controller.h +++ b/chrome/browser/cocoa/content_blocked_bubble_controller.h @@ -29,6 +29,7 @@ typedef std::map<NSButton*, int> PopupLinks; IBOutlet NSButton* manageButton_; IBOutlet NSButton* doneButton_; + IBOutlet NSButton* loadAllPluginsButton_; // The container for the bubble contents of the geolocation bubble. IBOutlet NSView* contentsContainer_; @@ -59,4 +60,7 @@ typedef std::map<NSButton*, int> PopupLinks; // Callback for "info" link. - (IBAction)showMoreInfo:(id)sender; +// Callback for "load all plugins" button. +- (IBAction)loadAllPlugins:(id)sender; + @end diff --git a/chrome/browser/cocoa/content_blocked_bubble_controller.mm b/chrome/browser/cocoa/content_blocked_bubble_controller.mm index 8f3d613..494a3c9 100644 --- a/chrome/browser/cocoa/content_blocked_bubble_controller.mm +++ b/chrome/browser/cocoa/content_blocked_bubble_controller.mm @@ -46,6 +46,10 @@ const int kGeoLabelHeight = 14; // Height of the "Clear" button in the geolocation bubble. const int kGeoClearButtonHeight = 17; +// Padding between radio buttons and "Load all plugins" button +// in the plugin bubble. +const int kLoadAllPluginsButtonVerticalPadding = 8; + // General padding between elements in the geolocation bubble. const int kGeoPadding = 8; @@ -87,6 +91,7 @@ NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) { - (void)initializeRadioGroup; - (void)initializePopupList; - (void)initializeGeoLists; +- (void)sizeToFitLoadPluginsButton; - (void)sizeToFitManageDoneButtons; - (void)removeInfoButton; - (void)popupLinkClicked:(id)sender; @@ -345,6 +350,36 @@ NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) { [contentsContainer_ setFrame:containerFrame]; } +- (void)sizeToFitLoadPluginsButton { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableClickToPlay)) { + const ContentSettingBubbleModel::BubbleContent& content = + contentSettingBubbleModel_->bubble_content(); + [loadAllPluginsButton_ setEnabled:content.load_plugins_link_enabled]; + + // Resize horizontally to fit button if necessary. + NSRect windowFrame = [[self window] frame]; + int widthNeeded = NSWidth([loadAllPluginsButton_ frame]) + + 2 * NSMinX([loadAllPluginsButton_ frame]); + if (NSWidth(windowFrame) < widthNeeded) { + windowFrame.size.width = widthNeeded; + [[self window] setFrame:windowFrame display:NO]; + } + } else { + // Remove button and resize vertically. + int deltaY = kLoadAllPluginsButtonVerticalPadding + + NSHeight([loadAllPluginsButton_ frame]); + [loadAllPluginsButton_ removeFromSuperview]; + NSRect frame = [[self window] frame]; + frame.size.height -= deltaY; + [[self window] setFrame:frame display:NO]; + NSPoint radioOrigin = [allowBlockRadioGroup_ frame].origin; + radioOrigin.y -= deltaY; + [allowBlockRadioGroup_ setFrameOrigin:radioOrigin]; + [allowBlockRadioGroup_ setNeedsDisplay]; + } +} + - (void)sizeToFitManageDoneButtons { CGFloat actualWidth = NSWidth([[[self window] contentView] frame]); CGFloat requiredWidth = NSMaxX([manageButton_ frame]) + kManageDonePadding + @@ -381,16 +416,18 @@ NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) { [self sizeToFitManageDoneButtons]; [self initializeTitle]; - if (contentSettingBubbleModel_->content_type() == - CONTENT_SETTINGS_TYPE_COOKIES) + + ContentSettingsType type = contentSettingBubbleModel_->content_type(); + if (type == CONTENT_SETTINGS_TYPE_PLUGINS) + [self sizeToFitLoadPluginsButton]; + if (type == CONTENT_SETTINGS_TYPE_COOKIES) [self removeInfoButton]; if (allowBlockRadioGroup_) // not bound in cookie bubble xib [self initializeRadioGroup]; - if (contentSettingBubbleModel_->content_type() == - CONTENT_SETTINGS_TYPE_POPUPS) + + if (type == CONTENT_SETTINGS_TYPE_POPUPS) [self initializePopupList]; - if (contentSettingBubbleModel_->content_type() == - CONTENT_SETTINGS_TYPE_GEOLOCATION) + if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) [self initializeGeoLists]; } @@ -416,6 +453,11 @@ NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) { [self close]; } +- (IBAction)loadAllPlugins:(id)sender { + contentSettingBubbleModel_->OnLoadPluginsLinkClicked(); + [self close]; +} + - (void)popupLinkClicked:(id)sender { content_blocked_bubble::PopupLinks::iterator i(popupLinks_.find(sender)); DCHECK(i != popupLinks_.end()); diff --git a/chrome/browser/content_setting_bubble_model.cc b/chrome/browser/content_setting_bubble_model.cc index 88bb04d..2b8e190 100644 --- a/chrome/browser/content_setting_bubble_model.cc +++ b/chrome/browser/content_setting_bubble_model.cc @@ -11,6 +11,7 @@ #include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/common/chrome_switches.h" @@ -177,6 +178,37 @@ class ContentSettingSingleRadioGroup : public ContentSettingTitleAndLinkModel { } }; +class ContentSettingPluginBubbleModel : public ContentSettingSingleRadioGroup { + public: + ContentSettingPluginBubbleModel(TabContents* tab_contents, Profile* profile, + ContentSettingsType content_type) + : ContentSettingSingleRadioGroup(tab_contents, profile, content_type) { + DCHECK_EQ(content_type, CONTENT_SETTINGS_TYPE_PLUGINS); + SetLoadPluginsLinkTitle(); + } + + private: + void SetLoadPluginsLinkTitle() { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableClickToPlay)) { + set_load_plugins_link_title( + l10n_util::GetStringUTF8(IDS_BLOCKED_PLUGINS_LOAD_ALL)); + } + } + + virtual void OnLoadPluginsLinkClicked() { + DCHECK(CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableClickToPlay)); + if (tab_contents()) { + tab_contents()->render_view_host()->LoadBlockedPlugins(); + } + set_load_plugins_link_enabled(false); + TabSpecificContentSettings* settings = + tab_contents()->GetTabSpecificContentSettings(); + settings->set_load_plugins_link_enabled(false); + } +}; + class ContentSettingPopupBubbleModel : public ContentSettingSingleRadioGroup { public: ContentSettingPopupBubbleModel(TabContents* tab_contents, Profile* profile, @@ -304,6 +336,10 @@ ContentSettingBubbleModel* return new ContentSettingDomainListBubbleModel(tab_contents, profile, content_type); } + if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) { + return new ContentSettingPluginBubbleModel(tab_contents, profile, + content_type); + } return new ContentSettingSingleRadioGroup(tab_contents, profile, content_type); } @@ -313,6 +349,13 @@ ContentSettingBubbleModel::ContentSettingBubbleModel( ContentSettingsType content_type) : tab_contents_(tab_contents), profile_(profile), content_type_(content_type) { + if (tab_contents) { + TabSpecificContentSettings* settings = + tab_contents->GetTabSpecificContentSettings(); + set_load_plugins_link_enabled(settings->load_plugins_link_enabled()); + } else { + set_load_plugins_link_enabled(true); + } registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, Source<TabContents>(tab_contents)); } diff --git a/chrome/browser/content_setting_bubble_model.h b/chrome/browser/content_setting_bubble_model.h index fd56ef8..3d7c08a 100644 --- a/chrome/browser/content_setting_bubble_model.h +++ b/chrome/browser/content_setting_bubble_model.h @@ -61,6 +61,8 @@ class ContentSettingBubbleModel : public NotificationObserver { std::string manage_link; std::string clear_link; std::string info_link; + std::string load_plugins_link_title; + bool load_plugins_link_enabled; }; const BubbleContent& bubble_content() const { return bubble_content_; } @@ -75,6 +77,7 @@ class ContentSettingBubbleModel : public NotificationObserver { virtual void OnManageLinkClicked() {} virtual void OnClearLinkClicked() {} virtual void OnInfoLinkClicked() {} + virtual void OnLoadPluginsLinkClicked() {} protected: ContentSettingBubbleModel(TabContents* tab_contents, Profile* profile, @@ -102,6 +105,12 @@ class ContentSettingBubbleModel : public NotificationObserver { void set_info_link(const std::string& link) { bubble_content_.info_link = link; } + void set_load_plugins_link_title(const std::string& title) { + bubble_content_.load_plugins_link_title = title; + } + void set_load_plugins_link_enabled(bool enabled) { + bubble_content_.load_plugins_link_enabled = enabled; + } private: TabContents* tab_contents_; diff --git a/chrome/browser/content_setting_bubble_model_unittest.cc b/chrome/browser/content_setting_bubble_model_unittest.cc index 5f96e49..7a77fb9 100644 --- a/chrome/browser/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/content_setting_bubble_model_unittest.cc @@ -38,6 +38,7 @@ class ContentSettingBubbleModelTest : public RenderViewHostTestHarness { EXPECT_NE(std::string(), bubble_content.manage_link); EXPECT_EQ(std::string(), bubble_content.info_link); EXPECT_EQ(std::string(), bubble_content.title); + EXPECT_EQ(std::string(), bubble_content.load_plugins_link_title); } ChromeThread ui_thread_; @@ -58,6 +59,7 @@ TEST_F(ContentSettingBubbleModelTest, ImageRadios) { EXPECT_NE(std::string(), bubble_content.manage_link); EXPECT_EQ(std::string(), bubble_content.info_link); EXPECT_NE(std::string(), bubble_content.title); + EXPECT_EQ(std::string(), bubble_content.load_plugins_link_title); } TEST_F(ContentSettingBubbleModelTest, Cookies) { @@ -74,6 +76,24 @@ TEST_F(ContentSettingBubbleModelTest, Cookies) { EXPECT_NE(std::string(), bubble_content.manage_link); EXPECT_NE(std::string(), bubble_content.info_link); EXPECT_NE(std::string(), bubble_content.title); + EXPECT_EQ(std::string(), bubble_content.load_plugins_link_title); +} + +TEST_F(ContentSettingBubbleModelTest, Plugins) { + TabSpecificContentSettings* content_settings = + contents()->GetTabSpecificContentSettings(); + content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS); + + scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( + ContentSettingBubbleModel::CreateContentSettingBubbleModel( + contents(), profile_.get(), CONTENT_SETTINGS_TYPE_PLUGINS)); + const ContentSettingBubbleModel::BubbleContent& bubble_content = + content_setting_bubble_model->bubble_content(); + EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); + EXPECT_NE(std::string(), bubble_content.manage_link); + EXPECT_EQ(std::string(), bubble_content.info_link); + EXPECT_NE(std::string(), bubble_content.title); + EXPECT_EQ(std::string(), bubble_content.load_plugins_link_title); } TEST_F(ContentSettingBubbleModelTest, Geolocation) { diff --git a/chrome/browser/gtk/content_setting_bubble_gtk.cc b/chrome/browser/gtk/content_setting_bubble_gtk.cc index f285fd8..d0d4a56 100644 --- a/chrome/browser/gtk/content_setting_bubble_gtk.cc +++ b/chrome/browser/gtk/content_setting_bubble_gtk.cc @@ -197,6 +197,22 @@ void ContentSettingBubbleGtk::BuildBubble() { FALSE, FALSE, 0); } + if (!content.load_plugins_link_title.empty()) { + GtkWidget* load_plugins_link_box = gtk_hbox_new(FALSE, 0); + GtkWidget* load_plugins_link = gtk_chrome_link_button_new( + content.load_plugins_link_title.c_str()); + gtk_widget_set_sensitive(load_plugins_link, + content.load_plugins_link_enabled); + g_signal_connect(load_plugins_link, "clicked", + G_CALLBACK(OnLoadPluginsLinkClickedThunk), this); + gtk_box_pack_start(GTK_BOX(load_plugins_link_box), load_plugins_link, + FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(bubble_content), load_plugins_link_box, + 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); GtkWidget* manage_link = @@ -281,3 +297,8 @@ void ContentSettingBubbleGtk::OnInfoLinkClicked(GtkWidget* button) { content_setting_bubble_model_->OnInfoLinkClicked(); Close(); } + +void ContentSettingBubbleGtk::OnLoadPluginsLinkClicked(GtkWidget* button) { + content_setting_bubble_model_->OnLoadPluginsLinkClicked(); + Close(); +} diff --git a/chrome/browser/gtk/content_setting_bubble_gtk.h b/chrome/browser/gtk/content_setting_bubble_gtk.h index 94b8e17..3859b30 100644 --- a/chrome/browser/gtk/content_setting_bubble_gtk.h +++ b/chrome/browser/gtk/content_setting_bubble_gtk.h @@ -60,6 +60,7 @@ class ContentSettingBubbleGtk : public InfoBubbleGtkDelegate, CHROMEGTK_CALLBACK_0(ContentSettingBubbleGtk, void, OnManageLinkClicked); CHROMEGTK_CALLBACK_0(ContentSettingBubbleGtk, void, OnClearLinkClicked); CHROMEGTK_CALLBACK_0(ContentSettingBubbleGtk, void, OnInfoLinkClicked); + CHROMEGTK_CALLBACK_0(ContentSettingBubbleGtk, void, OnLoadPluginsLinkClicked); // We position the bubble near this widget. GtkWidget* anchor_; @@ -88,6 +89,8 @@ class ContentSettingBubbleGtk : public InfoBubbleGtkDelegate, typedef std::vector<GtkWidget*> RadioGroupGtk; RadioGroupGtk radio_group_gtk_; + + GtkWidget* load_plugins_link_; }; #endif // CHROME_BROWSER_GTK_CONTENT_SETTING_BUBBLE_GTK_H_ diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index ccaa30a..c3a7713 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -652,6 +652,10 @@ void RenderViewHost::InstallMissingPlugin() { Send(new ViewMsg_InstallMissingPlugin(routing_id())); } +void RenderViewHost::LoadBlockedPlugins() { + Send(new ViewMsg_LoadBlockedPlugins(routing_id())); +} + void RenderViewHost::FilesSelectedInChooser( const std::vector<FilePath>& files) { // Grant the security access requested to the given files. diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 4683f7a..ff5ff94 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -345,6 +345,9 @@ class RenderViewHost : public RenderWidgetHost { // missing plugin. Called by PluginInstaller. void InstallMissingPlugin(); + // Load all blocked plugins in the RenderView. + void LoadBlockedPlugins(); + // Get all savable resource links from current webpage, include main // frame and sub-frame. void GetAllSavableResourceLinksForCurrentPage(const GURL& page_url); diff --git a/chrome/browser/tab_contents/tab_specific_content_settings.cc b/chrome/browser/tab_contents/tab_specific_content_settings.cc index 57b9a2b..b09992c 100644 --- a/chrome/browser/tab_contents/tab_specific_content_settings.cc +++ b/chrome/browser/tab_contents/tab_specific_content_settings.cc @@ -102,6 +102,7 @@ TabSpecificContentSettings::TabSpecificContentSettings( : allowed_local_shared_objects_(profile), blocked_local_shared_objects_(profile), geolocation_settings_state_(profile), + load_plugins_link_enabled_(true), delegate_(NULL) { ClearBlockedContentSettings(); delegate_ = delegate; @@ -110,6 +111,7 @@ TabSpecificContentSettings::TabSpecificContentSettings( void TabSpecificContentSettings::ClearBlockedContentSettings() { for (size_t i = 0; i < arraysize(content_blocked_); ++i) content_blocked_[i] = false; + load_plugins_link_enabled_ = true; blocked_local_shared_objects_.Reset(); allowed_local_shared_objects_.Reset(); if (delegate_) diff --git a/chrome/browser/tab_contents/tab_specific_content_settings.h b/chrome/browser/tab_contents/tab_specific_content_settings.h index 9e2148d..157976b 100644 --- a/chrome/browser/tab_contents/tab_specific_content_settings.h +++ b/chrome/browser/tab_contents/tab_specific_content_settings.h @@ -65,6 +65,11 @@ class TabSpecificContentSettings // Returns a CookiesTreeModel object for the recoreded blocked cookies. CookiesTreeModel* GetBlockedCookiesTreeModel(); + bool load_plugins_link_enabled() { return load_plugins_link_enabled_; } + void set_load_plugins_link_enabled(bool enabled) { + load_plugins_link_enabled_ = enabled; + } + // RenderViewHostDelegate::ContentSettings implementation. virtual void OnContentBlocked(ContentSettingsType type); virtual void OnCookieAccessed(const GURL& url, @@ -122,6 +127,9 @@ class TabSpecificContentSettings // Manages information about Geolocation API usage in this page. GeolocationSettingsState geolocation_settings_state_; + // Stores whether the user can load blocked plugins on this page. + bool load_plugins_link_enabled_; + Delegate* delegate_; DISALLOW_COPY_AND_ASSIGN(TabSpecificContentSettings); diff --git a/chrome/browser/views/content_blocked_bubble_contents.cc b/chrome/browser/views/content_blocked_bubble_contents.cc index bef80be..11bdded 100644 --- a/chrome/browser/views/content_blocked_bubble_contents.cc +++ b/chrome/browser/views/content_blocked_bubble_contents.cc @@ -103,7 +103,8 @@ ContentSettingBubbleContents::ContentSettingBubbleContents( close_button_(NULL), manage_link_(NULL), clear_link_(NULL), - info_link_(NULL) { + info_link_(NULL), + load_plugins_link_(NULL) { registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, Source<TabContents>(tab_contents)); } @@ -157,6 +158,12 @@ void ContentSettingBubbleContents::LinkActivated(views::Link* source, info_bubble_->Close(); // CAREFUL: This deletes us. return; } + if (source == load_plugins_link_) { + content_setting_bubble_model_->OnLoadPluginsLinkClicked(); + info_bubble_->set_fade_away_on_close(true); + info_bubble_->Close(); // CAREFUL: This deletes us. + return; + } PopupLinks::const_iterator i(popup_links_.find(source)); DCHECK(i != popup_links_.end()); @@ -303,6 +310,21 @@ void ContentSettingBubbleContents::InitControlLayout() { layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); } + if (!bubble_content.load_plugins_link_title.empty()) { + load_plugins_link_ = new views::Link( + UTF8ToWide(bubble_content.load_plugins_link_title)); + load_plugins_link_->SetEnabled(bubble_content.load_plugins_link_enabled); + load_plugins_link_->SetController(this); + layout->StartRow(0, single_column_set_id); + layout->AddView(load_plugins_link_); + + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + layout->StartRow(0, single_column_set_id); + layout->AddView(new views::Separator, 1, 1, + GridLayout::FILL, GridLayout::FILL); + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + } + const int double_column_set_id = 1; views::ColumnSet* double_column_set = layout->AddColumnSet(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 a48cfcbc..6d6c72c 100644 --- a/chrome/browser/views/content_blocked_bubble_contents.h +++ b/chrome/browser/views/content_blocked_bubble_contents.h @@ -95,6 +95,7 @@ class ContentSettingBubbleContents : public views::View, views::Link* manage_link_; views::Link* clear_link_; views::Link* info_link_; + views::Link* load_plugins_link_; DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingBubbleContents); }; |