diff options
author | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-15 05:14:17 +0000 |
---|---|---|
committer | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-15 05:14:17 +0000 |
commit | 4742bde23a97f35c177a99782800dbf5ca472b85 (patch) | |
tree | 90229b975e7ceca25e8847fb09f18142511bcc18 | |
parent | 5ed6b4017d6dfe03e9a790c2a4c2a5dcfa9736db (diff) | |
download | chromium_src-4742bde23a97f35c177a99782800dbf5ca472b85.zip chromium_src-4742bde23a97f35c177a99782800dbf5ca472b85.tar.gz chromium_src-4742bde23a97f35c177a99782800dbf5ca472b85.tar.bz2 |
Refactor UI "badge" (page action) logic into a BadgeController interface,
and convert the GTK code to use it (mac/views come next).
This is for the currentTab permission work where the page action area will
be used to display icons for extensions with scripts running on the current
page ("script badges"), and will also need to have various different UIs for
them (hence the "decoration" stuff). To implement this I plan on injecting
a different BadgeController implementation given a command line flag for the
new behaviour.
BUG=127988
Review URL: https://chromiumcodereview.appspot.com/10381105
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137079 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/action_box_controller.h | 58 | ||||
-rw-r--r-- | chrome/browser/extensions/page_action_controller.cc | 76 | ||||
-rw-r--r-- | chrome/browser/extensions/page_action_controller.h | 38 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/location_bar_view_gtk.cc | 71 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/location_bar_view_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.cc | 3 | ||||
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.h | 6 | ||||
-rw-r--r-- | chrome/chrome_browser_extensions.gypi | 3 |
8 files changed, 221 insertions, 37 deletions
diff --git a/chrome/browser/extensions/action_box_controller.h b/chrome/browser/extensions/action_box_controller.h new file mode 100644 index 0000000..e3415c7 --- /dev/null +++ b/chrome/browser/extensions/action_box_controller.h @@ -0,0 +1,58 @@ +// Copyright (c) 2012 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_EXTENSIONS_ACTION_BOX_CONTROLLER_H_ +#define CHROME_BROWSER_EXTENSIONS_ACTION_BOX_CONTROLLER_H_ +#pragma once + +#include <string> +#include <vector> + +#include "base/memory/scoped_ptr.h" + +class ExtensionAction; + +namespace extensions { + +// Controller of the "badges" (aka "page actions") in the UI. +class ActionBoxController { + public: + // UI decoration on a page box item. + enum Decoration { + DECORATION_NONE, + }; + + // Data about a UI badge. + struct Data { + // The type of decoration that should be applied to the badge. + Decoration decoration; + + // The ExtensionAction that corresponds to the badge. + ExtensionAction* action; + }; + + typedef std::vector<Data> DataList; + + // The reaction that the UI should take after executing |OnClicked|. + enum Action { + ACTION_NONE, + ACTION_SHOW_POPUP, + ACTION_SHOW_CONTEXT_MENU, + }; + + virtual ~ActionBoxController() {} + + // Gets the badge data for all extensions. + virtual scoped_ptr<DataList> GetAllBadgeData() = 0; + + // Notifies this that the badge for an extension has been clicked with some + // mouse button (1 for left, 2 for middle, and 3 for right click), and + // returns the action that should be taken in response (if any). + virtual Action OnClicked(const std::string& extension_id, + int mouse_button) = 0; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_ACTION_BOX_CONTROLLER_H_ diff --git a/chrome/browser/extensions/page_action_controller.cc b/chrome/browser/extensions/page_action_controller.cc new file mode 100644 index 0000000..c21b768 --- /dev/null +++ b/chrome/browser/extensions/page_action_controller.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2012 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/extensions/page_action_controller.h" + +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/extensions/extension_browser_event_router.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/common/extensions/extension_set.h" +#include "content/public/browser/web_contents.h" + +namespace extensions { + +PageActionController::PageActionController(TabContentsWrapper* tab_contents) + : tab_contents_(tab_contents) {} + +PageActionController::~PageActionController() {} + +scoped_ptr<ActionBoxController::DataList> +PageActionController::GetAllBadgeData() { + const ExtensionSet* extensions = GetExtensionService()->extensions(); + scoped_ptr<DataList> all_badge_data(new DataList()); + for (ExtensionSet::const_iterator i = extensions->begin(); + i != extensions->end(); ++i) { + ExtensionAction* action = (*i)->page_action(); + if (action) { + Data data = { + DECORATION_NONE, + action, + }; + all_badge_data->push_back(data); + } + } + return all_badge_data.Pass(); +} + +ActionBoxController::Action PageActionController::OnClicked( + const std::string& extension_id, int mouse_button) { + const Extension* extension = + GetExtensionService()->extensions()->GetByID(extension_id); + CHECK(extension); + ExtensionAction* page_action = extension->page_action(); + CHECK(page_action); + int tab_id = ExtensionTabUtil::GetTabId(tab_contents_->web_contents()); + + switch (mouse_button) { + case 1: + case 2: + if (page_action->HasPopup(tab_id)) + return ACTION_SHOW_POPUP; + + GetExtensionService()->browser_event_router()->PageActionExecuted( + tab_contents_->profile(), + extension->id(), + page_action->id(), + tab_id, + tab_contents_->web_contents()->GetURL().spec(), + mouse_button); + return ACTION_NONE; + + case 3: + return extension->ShowConfigureContextMenus() ? + ACTION_SHOW_CONTEXT_MENU : ACTION_NONE; + } + + return ACTION_NONE; +} + +ExtensionService* PageActionController::GetExtensionService() { + return ExtensionSystem::Get(tab_contents_->profile())->extension_service(); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/page_action_controller.h b/chrome/browser/extensions/page_action_controller.h new file mode 100644 index 0000000..22f9fc6 --- /dev/null +++ b/chrome/browser/extensions/page_action_controller.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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_EXTENSIONS_PAGE_ACTION_CONTROLLER_H_ +#define CHROME_BROWSER_EXTENSIONS_PAGE_ACTION_CONTROLLER_H_ +#pragma once + +#include "chrome/browser/extensions/action_box_controller.h" + +class ExtensionService; +class TabContentsWrapper; + +namespace extensions { + +// An ActionBoxController which corresponds to the page actions of an extension. +class PageActionController : public ActionBoxController { + public: + explicit PageActionController(TabContentsWrapper* tab_contents); + virtual ~PageActionController(); + + virtual scoped_ptr<DataList> GetAllBadgeData() OVERRIDE; + + virtual Action OnClicked(const std::string& extension_id, + int mouse_button) OVERRIDE; + + private: + // Gets the ExtensionService for |tab_contents_|. + ExtensionService* GetExtensionService(); + + TabContentsWrapper* tab_contents_; + + DISALLOW_COPY_AND_ASSIGN(PageActionController); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_PAGE_ACTION_CONTROLLER_H_ diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc index ec53c1e..3672740 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc @@ -26,6 +26,7 @@ #include "chrome/browser/defaults.h" #include "chrome/browser/extensions/api/commands/extension_command_service.h" #include "chrome/browser/extensions/api/commands/extension_command_service_factory.h" +#include "chrome/browser/extensions/action_box_controller.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_util.h" @@ -82,6 +83,7 @@ using content::NavigationEntry; using content::OpenURLParams; using content::WebContents; +using extensions::ActionBoxController; namespace { @@ -683,16 +685,12 @@ void LocationBarViewGtk::UpdateContentSettingsIcons() { } void LocationBarViewGtk::UpdatePageActions() { - std::vector<ExtensionAction*> page_actions; - ExtensionService* service = browser_->profile()->GetExtensionService(); - if (!service) - return; + ActionBoxController::DataList page_actions; - // Find all the page actions. - for (ExtensionSet::const_iterator it = service->extensions()->begin(); - it != service->extensions()->end(); ++it) { - if ((*it)->page_action()) - page_actions.push_back((*it)->page_action()); + TabContentsWrapper* tab_contents = GetTabContentsWrapper(); + if (tab_contents) { + page_actions.swap( + *tab_contents->extension_action_box_controller()->GetAllBadgeData()); } // Initialize on the first call, or re-inialize if more extensions have been @@ -702,7 +700,7 @@ void LocationBarViewGtk::UpdatePageActions() { for (size_t i = 0; i < page_actions.size(); ++i) { page_action_views_.push_back( - new PageActionViewGtk(this, page_actions[i])); + new PageActionViewGtk(this, page_actions[i].action)); gtk_box_pack_end(GTK_BOX(page_action_hbox_.get()), page_action_views_[i]->widget(), FALSE, FALSE, 0); } @@ -1681,17 +1679,6 @@ void LocationBarViewGtk::EnabledStateChangedForCommand(int id, bool enabled) { UpdateChromeToMobileIcon(); } -bool LocationBarViewGtk::PageActionViewGtk::ShowPopup() { - if (!page_action_->HasPopup(current_tab_id_)) - return false; - - ExtensionPopupGtk::Show( - page_action_->GetPopupUrl(current_tab_id_), - owner_->browser_, - event_box_.get()); - return true; -} - void LocationBarViewGtk::PageActionViewGtk::ConnectPageActionAccelerator() { const ExtensionSet* extensions = owner_->browser()->profile()-> GetExtensionService()->extensions(); @@ -1746,25 +1733,41 @@ void LocationBarViewGtk::PageActionViewGtk::DisconnectPageActionAccelerator() { gboolean LocationBarViewGtk::PageActionViewGtk::OnButtonPressed( GtkWidget* sender, GdkEventButton* event) { - Profile* profile = owner_->browser()->profile(); - if (event->button != 3) { - if (!ShowPopup()) { - ExtensionService* service = profile->GetExtensionService(); - service->browser_event_router()->PageActionExecuted(profile, - page_action_->extension_id(), page_action_->id(), current_tab_id_, - current_url_.spec(), event->button); - } - } else { - const Extension* extension = profile->GetExtensionService()-> - GetExtensionById(page_action()->extension_id(), false); + TabContentsWrapper* tab_contents = owner_->GetTabContentsWrapper(); + if (!tab_contents) + return TRUE; - if (extension->ShowConfigureContextMenus()) { + ExtensionService* extension_service = + owner_->browser()->profile()->GetExtensionService(); + if (!extension_service) + return TRUE; + + const Extension* extension = + extension_service->extensions()->GetByID(page_action()->extension_id()); + if (!extension) + return TRUE; + + ActionBoxController* controller = + tab_contents->extension_action_box_controller(); + + switch (controller->OnClicked(extension->id(), event->button)) { + case ActionBoxController::ACTION_NONE: + break; + + case ActionBoxController::ACTION_SHOW_POPUP: + ExtensionPopupGtk::Show( + page_action_->GetPopupUrl(current_tab_id_), + owner_->browser_, + event_box_.get()); + break; + + case ActionBoxController::ACTION_SHOW_CONTEXT_MENU: context_menu_model_ = new ExtensionContextMenuModel(extension, owner_->browser_); context_menu_.reset( new MenuGtk(NULL, context_menu_model_.get())); context_menu_->PopupForWidget(sender, event->button, event->time); - } + break; } return TRUE; diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h index ce9323b..4a0fbce 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.h +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h @@ -253,9 +253,6 @@ class LocationBarViewGtk : public AutocompleteEditController, const content::NotificationDetails& details) OVERRIDE; private: - // Show the popup for this page action. Returns true if a popup was shown. - bool ShowPopup(); - // Connect the accelerator for the page action popup. void ConnectPageActionAccelerator(); diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index 2d4dca2..a668433 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -14,6 +14,7 @@ #include "chrome/browser/download/download_request_limiter_observer.h" #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" #include "chrome/browser/extensions/extension_tab_helper.h" +#include "chrome/browser/extensions/page_action_controller.h" #include "chrome/browser/extensions/script_executor_impl.h" #include "chrome/browser/external_protocol/external_protocol_observer.h" #include "chrome/browser/favicon/favicon_tab_helper.h" @@ -96,6 +97,8 @@ TabContentsWrapper::TabContentsWrapper(WebContents* contents) extension_tab_helper_.reset(new ExtensionTabHelper(this)); extension_script_executor_.reset( new extensions::ScriptExecutorImpl(web_contents())); + extension_action_box_controller_.reset( + new extensions::PageActionController(this)); favicon_tab_helper_.reset(new FaviconTabHelper(contents)); find_tab_helper_.reset(new FindTabHelper(contents)); history_tab_helper_.reset(new HistoryTabHelper(contents)); diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index e128c85..c4fe4cc4 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -56,6 +56,7 @@ class SyncedTabDelegate; } namespace extensions { +class ActionBoxController; class ScriptExecutor; class WebNavigationTabObserver; } @@ -137,6 +138,10 @@ class TabContentsWrapper : public content::WebContentsObserver { return extension_script_executor_.get(); } + extensions::ActionBoxController* extension_action_box_controller() { + return extension_action_box_controller_.get(); + } + ExtensionTabHelper* extension_tab_helper() { return extension_tab_helper_.get(); } @@ -235,6 +240,7 @@ class TabContentsWrapper : public content::WebContentsObserver { scoped_ptr<CoreTabHelper> core_tab_helper_; scoped_ptr<extensions::ScriptExecutor> extension_script_executor_; scoped_ptr<ExtensionTabHelper> extension_tab_helper_; + scoped_ptr<extensions::ActionBoxController> extension_action_box_controller_; scoped_ptr<FaviconTabHelper> favicon_tab_helper_; scoped_ptr<FindTabHelper> find_tab_helper_; scoped_ptr<HistoryTabHelper> history_tab_helper_; diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 4b02624..8f4c755 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -53,6 +53,7 @@ 'sources': [ # All .cc, .h, .m, and .mm files under browser/extensions except for # tests and mocks. + 'browser/extensions/action_box_controller.h', 'browser/extensions/api/api_function.cc', 'browser/extensions/api/api_function.h', 'browser/extensions/api/api_resource.cc', @@ -380,6 +381,8 @@ 'browser/extensions/lazy_background_task_queue.h', 'browser/extensions/pack_extension_job.cc', 'browser/extensions/pack_extension_job.h', + 'browser/extensions/page_action_controller.cc', + 'browser/extensions/page_action_controller.h', 'browser/extensions/pending_extension_info.cc', 'browser/extensions/pending_extension_info.h', 'browser/extensions/pending_extension_manager.cc', |