Commit 4f88601f authored by kalman@chromium.org's avatar kalman@chromium.org

Make the page action space show extensions with active content scripts or

executed script when the action box is enabled.

This is platform independent but will only work on GTK until cocoa and views
have been updated to use the ActionBoxController interface.


BUG=127988


Review URL: https://chromiumcodereview.appspot.com/10332235

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138021 0039d316-1c4b-4281-b951-d872f2087c98
parent 57e61ee7
......@@ -6,6 +6,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/page_action_controller.h"
#include "chrome/browser/extensions/script_badge_controller.h"
#include "chrome/browser/extensions/script_executor_impl.h"
#include "chrome/browser/extensions/webstore_inline_installer.h"
#include "chrome/browser/profiles/profile.h"
......@@ -19,6 +20,7 @@
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/extensions/extension_switch_utils.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/notification_service.h"
......@@ -29,6 +31,7 @@
#include "ui/gfx/image/image.h"
using content::WebContents;
using extensions::ScriptBadgeController;
using extensions::ScriptExecutorImpl;
using extensions::PageActionController;
......@@ -45,8 +48,12 @@ ExtensionTabHelper::ExtensionTabHelper(TabContentsWrapper* wrapper)
ALLOW_THIS_IN_INITIALIZER_LIST(
extension_function_dispatcher_(wrapper->profile(), this)),
wrapper_(wrapper) {
script_executor_.reset(new ScriptExecutorImpl(wrapper->web_contents()));
action_box_controller_.reset(new PageActionController(wrapper, this));
if (extensions::switch_utils::IsActionBoxEnabled()) {
script_badge_controller_.reset(new ScriptBadgeController(wrapper));
} else {
script_executor_.reset(new ScriptExecutorImpl(wrapper->web_contents()));
action_box_controller_.reset(new PageActionController(wrapper, this));
}
}
ExtensionTabHelper::~ExtensionTabHelper() {
......@@ -111,6 +118,18 @@ SkBitmap* ExtensionTabHelper::GetExtensionAppIcon() {
return &extension_app_icon_;
}
extensions::ScriptExecutor* ExtensionTabHelper::script_executor() {
if (script_badge_controller_.get())
return script_badge_controller_.get();
return script_executor_.get();
}
extensions::ActionBoxController* ExtensionTabHelper::action_box_controller() {
if (script_badge_controller_.get())
return script_badge_controller_.get();
return action_box_controller_.get();
}
void ExtensionTabHelper::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
......
......@@ -27,6 +27,7 @@ struct LoadCommittedDetails;
namespace extensions {
class ActionBoxController;
class ScriptBadgeController;
class ScriptExecutor;
}
......@@ -109,13 +110,9 @@ class ExtensionTabHelper
return content::WebContentsObserver::web_contents();
}
extensions::ScriptExecutor* script_executor() {
return script_executor_.get();
}
extensions::ScriptExecutor* script_executor();
extensions::ActionBoxController* action_box_controller() {
return action_box_controller_.get();
}
extensions::ActionBoxController* action_box_controller();
// Sets a non-extension app icon associated with WebContents and fires an
// INVALIDATE_TYPE_TITLE navigation state change to trigger repaint of title.
......@@ -203,9 +200,12 @@ class ExtensionTabHelper
TabContentsWrapper* wrapper_;
// Either script_executor/action_box_controller will have values, or
// script_badge_controller will have a value, depending on whether the action
// box is turned on.
scoped_ptr<extensions::ScriptExecutor> script_executor_;
scoped_ptr<extensions::ActionBoxController> action_box_controller_;
scoped_ptr<extensions::ScriptBadgeController> script_badge_controller_;
DISALLOW_COPY_AND_ASSIGN(ExtensionTabHelper);
};
......
......@@ -53,8 +53,8 @@ ActionBoxController::Action PageActionController::OnClicked(
int tab_id = ExtensionTabUtil::GetTabId(tab_contents_->web_contents());
switch (mouse_button) {
case 1:
case 2:
case 1: // left
case 2: // middle
if (page_action->HasPopup(tab_id))
return ACTION_SHOW_POPUP;
......@@ -67,7 +67,7 @@ ActionBoxController::Action PageActionController::OnClicked(
mouse_button);
return ACTION_NONE;
case 3:
case 3: // right
return extension->ShowConfigureContextMenus() ?
ACTION_SHOW_CONTEXT_MENU : ACTION_NONE;
}
......
// 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/script_badge_controller.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "grit/theme_resources.h"
#include "ui/base/resource/resource_bundle.h"
namespace extensions {
ScriptBadgeController::ScriptBadgeController(TabContentsWrapper* tab_contents)
: content::WebContentsObserver(tab_contents->web_contents()),
script_executor_(tab_contents->web_contents()),
tab_contents_(tab_contents) {
}
ScriptBadgeController::~ScriptBadgeController() {
}
scoped_ptr<std::vector<ExtensionAction*> >
ScriptBadgeController::GetCurrentActions() {
const GURL& current_url = tab_contents_->web_contents()->GetURL();
const ExtensionSet* extensions = GetExtensionService()->extensions();
scoped_ptr<std::vector<ExtensionAction*> > current_actions(
new std::vector<ExtensionAction*>());
for (ExtensionSet::const_iterator it = extensions->begin();
it != extensions->end(); ++it) {
const Extension* extension = *it;
if (extension->HasContentScriptAtURL(current_url) ||
extensions_executing_scripts_.count(extension->id())) {
current_actions->push_back(GetScriptBadge(extension));
}
}
return current_actions.Pass();
}
ActionBoxController::Action ScriptBadgeController::OnClicked(
const std::string& extension_id, int mouse_button) {
const Extension* extension =
GetExtensionService()->extensions()->GetByID(extension_id);
CHECK(extension);
switch (mouse_button) {
case 3: // right
return extension->ShowConfigureContextMenus() ?
ACTION_SHOW_CONTEXT_MENU : ACTION_NONE;
}
return ACTION_NONE;
}
void ScriptBadgeController::ExecuteScript(
const std::string& extension_id,
ScriptExecutor::ScriptType script_type,
const std::string& code,
ScriptExecutor::FrameScope frame_scope,
UserScript::RunLocation run_at,
ScriptExecutor::WorldType world_type,
const ExecuteScriptCallback& callback) {
script_executor_.ExecuteScript(extension_id,
script_type,
code,
frame_scope,
run_at,
world_type,
callback);
// This tab should now show that the extension executing a script.
extensions_executing_scripts_.insert(extension_id);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_EXTENSION_ACTION_BOX_UPDATED,
content::Source<Profile>(tab_contents_->profile()),
content::Details<TabContentsWrapper>(tab_contents_));
}
void ScriptBadgeController::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
extensions_executing_scripts_.clear();
}
ExtensionAction* ScriptBadgeController::GetScriptBadge(
const Extension* extension) {
ScriptBadgeMap::iterator existing = script_badges_.find(extension->id());
if (existing != script_badges_.end())
return existing->second.get();
linked_ptr<ExtensionAction> badge(new ExtensionAction(extension->id()));
badge->SetTitle(ExtensionAction::kDefaultTabId, extension->name());
badge->SetIsVisible(ExtensionAction::kDefaultTabId, true);
// If there are existing actions, and they have default icon paths, use those.
// Otherwise we'll need to use the default icon and set it for all tabs.
std::string default_icon_path;
if (extension->browser_action())
default_icon_path = extension->browser_action()->default_icon_path();
else if (extension->page_action())
default_icon_path = extension->page_action()->default_icon_path();
if (!default_icon_path.empty()) {
badge->set_default_icon_path(default_icon_path);
} else {
badge->SetIcon(
ExtensionAction::kDefaultTabId,
*ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_EXTENSIONS_FAVICON).ToSkBitmap());
}
script_badges_[extension->id()] = badge;
return badge.get();
}
ExtensionService* ScriptBadgeController::GetExtensionService() {
return ExtensionSystem::Get(tab_contents_->profile())->extension_service();
}
} // namespace extensions
// 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_SCRIPT_BADGE_CONTROLLER_H_
#define CHROME_BROWSER_EXTENSIONS_SCRIPT_BADGE_CONTROLLER_H_
#pragma once
#include <map>
#include <set>
#include <string>
#include "base/memory/linked_ptr.h"
#include "chrome/browser/extensions/action_box_controller.h"
#include "chrome/browser/extensions/script_executor.h"
#include "chrome/browser/extensions/script_executor_impl.h"
#include "content/public/browser/web_contents_observer.h"
class Extension;
class ExtensionAction;
class ExtensionService;
class TabContentsWrapper;
namespace extensions {
// An ActionBoxController which corresponds to script badges, and implements
// ScriptExecutor in order to show those scripts in the action box too.
class ScriptBadgeController : public ActionBoxController,
public ScriptExecutor,
public content::WebContentsObserver {
public:
explicit ScriptBadgeController(TabContentsWrapper* tab_contents);
virtual ~ScriptBadgeController();
// ActionBoxController implementation.
virtual scoped_ptr<std::vector<ExtensionAction*> > GetCurrentActions()
OVERRIDE;
virtual Action OnClicked(const std::string& extension_id,
int mouse_button) OVERRIDE;
// ScriptExecutor implementation.
virtual void ExecuteScript(const std::string& extension_id,
ScriptType script_type,
const std::string& code,
FrameScope frame_scope,
UserScript::RunLocation run_at,
WorldType world_type,
const ExecuteScriptCallback& callback) OVERRIDE;
// content::WebContentsObserver implementation.
virtual void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) OVERRIDE;
private:
// Gets the script badge for |extension|.
ExtensionAction* GetScriptBadge(const Extension* extension);
// Gets the ExtensionService for |tab_contents_|.
ExtensionService* GetExtensionService();
// Delegate ScriptExecutorImpl for running ExecuteScript.
ScriptExecutorImpl script_executor_;
// Our parent TabContentsWrapper.
TabContentsWrapper* tab_contents_;
// The extensions that have called ExecuteScript on the current frame.
std::set<std::string> extensions_executing_scripts_;
// Script badges that have been generated for extensions. This is both those
// with actions already declared that are copied and normalised, and actions
// that get generated for extensions that haven't declared anything.
typedef std::map<std::string, linked_ptr<ExtensionAction> > ScriptBadgeMap;
ScriptBadgeMap script_badges_;
DISALLOW_COPY_AND_ASSIGN(ScriptBadgeController);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_SCRIPT_BADGE_CONTROLLER_H_
......@@ -414,6 +414,8 @@
'browser/extensions/process_map.h',
'browser/extensions/sandboxed_extension_unpacker.cc',
'browser/extensions/sandboxed_extension_unpacker.h',
'browser/extensions/script_badge_controller.cc',
'browser/extensions/script_badge_controller.h',
'browser/extensions/script_executor.h',
'browser/extensions/script_executor_impl.cc',
'browser/extensions/script_executor_impl.h',
......
......@@ -3492,6 +3492,15 @@ bool Extension::ShouldDisplayInExtensionSettings() const {
return true;
}
bool Extension::HasContentScriptAtURL(const GURL& url) const {
for (UserScriptList::const_iterator it = content_scripts_.begin();
it != content_scripts_.end(); ++it) {
if (it->MatchesURL(url))
return true;
}
return false;
}
bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) {
if (!is_platform_app())
return true;
......
......@@ -534,6 +534,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// settings page (i.e. chrome://extensions).
bool ShouldDisplayInExtensionSettings() const;
// Returns true if the extension has a content script declared at |url|.
bool HasContentScriptAtURL(const GURL& url) const;
// Accessors:
const FilePath& path() const { return path_; }
......
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