page_action_controller.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/page_action_controller.h"
6
7#include "chrome/browser/extensions/browser_event_router.h"
8#include "chrome/browser/extensions/component_loader.h"
9#include "chrome/browser/extensions/extension_action.h"
10#include "chrome/browser/extensions/extension_action_manager.h"
11#include "chrome/browser/extensions/extension_service.h"
12#include "chrome/browser/extensions/extension_system.h"
13#include "chrome/browser/extensions/extension_tab_util.h"
14#include "chrome/browser/extensions/tab_helper.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/sessions/session_id.h"
17#include "chrome/common/chrome_notification_types.h"
18#include "chrome/common/extensions/extension_set.h"
19#include "content/public/browser/invalidate_type.h"
20#include "content/public/browser/navigation_details.h"
21#include "content/public/browser/notification_service.h"
22#include "content/public/browser/web_contents.h"
23
24namespace extensions {
25
26PageActionController::PageActionController(content::WebContents* web_contents)
27    : content::WebContentsObserver(web_contents) {}
28
29PageActionController::~PageActionController() {}
30
31std::vector<ExtensionAction*> PageActionController::GetCurrentActions() const {
32  ExtensionService* service = GetExtensionService();
33  if (!service)
34    return std::vector<ExtensionAction*>();
35
36  // Accumulate the list of all page actions to display.
37  std::vector<ExtensionAction*> current_actions;
38
39  ExtensionActionManager* extension_action_manager =
40      ExtensionActionManager::Get(profile());
41
42  for (ExtensionSet::const_iterator i = service->extensions()->begin();
43       i != service->extensions()->end(); ++i) {
44    ExtensionAction* action =
45        extension_action_manager->GetPageAction(*i->get());
46    if (action)
47      current_actions.push_back(action);
48  }
49
50  return current_actions;
51}
52
53LocationBarController::Action PageActionController::OnClicked(
54    const std::string& extension_id, int mouse_button) {
55  ExtensionService* service = GetExtensionService();
56  if (!service)
57    return ACTION_NONE;
58
59  const Extension* extension = service->extensions()->GetByID(extension_id);
60  CHECK(extension);
61  ExtensionAction* page_action =
62      ExtensionActionManager::Get(profile())->GetPageAction(*extension);
63  CHECK(page_action);
64  int tab_id = ExtensionTabUtil::GetTabId(web_contents());
65
66  extensions::TabHelper::FromWebContents(web_contents())->
67      active_tab_permission_granter()->GrantIfRequested(extension);
68
69  switch (mouse_button) {
70    case 1:  // left
71    case 2:  // middle
72      if (page_action->HasPopup(tab_id))
73        return ACTION_SHOW_POPUP;
74
75      GetExtensionService()->browser_event_router()->PageActionExecuted(
76          profile(), *page_action, tab_id,
77          web_contents()->GetURL().spec(), mouse_button);
78      return ACTION_NONE;
79
80    case 3:  // right
81      return extension->ShowConfigureContextMenus() ?
82          ACTION_SHOW_CONTEXT_MENU : ACTION_NONE;
83  }
84
85  return ACTION_NONE;
86}
87
88void PageActionController::NotifyChange() {
89  web_contents()->NotifyNavigationStateChanged(
90      content::INVALIDATE_TYPE_PAGE_ACTIONS);
91}
92
93void PageActionController::DidNavigateMainFrame(
94    const content::LoadCommittedDetails& details,
95    const content::FrameNavigateParams& params) {
96  if (details.is_in_page)
97    return;
98
99  const std::vector<ExtensionAction*> current_actions = GetCurrentActions();
100
101  if (current_actions.empty())
102    return;
103
104  for (size_t i = 0; i < current_actions.size(); ++i) {
105    current_actions[i]->ClearAllValuesForTab(
106        SessionID::IdForTab(web_contents()));
107  }
108
109  NotifyChange();
110}
111
112Profile* PageActionController::profile() const {
113  return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
114}
115
116ExtensionService* PageActionController::GetExtensionService() const {
117  return ExtensionSystem::Get(profile())->extension_service();
118}
119
120}  // namespace extensions
121