This source file includes following definitions.
- Create
- GetType
- Apply
- Revert
- GetPageAction
- Create
#include "chrome/browser/extensions/api/declarative_content/content_action.h"
#include <map>
#include "base/lazy_instance.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_content/content_constants.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
namespace extensions {
namespace keys = declarative_content_constants;
namespace {
const char kInvalidInstanceTypeError[] =
"An action has an invalid instanceType: %s";
const char kNoPageAction[] =
"Can't use declarativeContent.ShowPageAction without a page action";
#define INPUT_FORMAT_VALIDATE(test) do { \
if (!(test)) { \
*bad_message = true; \
return scoped_refptr<ContentAction>(NULL); \
} \
} while (0)
class ShowPageAction : public ContentAction {
public:
ShowPageAction() {}
static scoped_refptr<ContentAction> Create(const Extension* extension,
const base::DictionaryValue* dict,
std::string* error,
bool* bad_message) {
if (ActionInfo::GetPageActionInfo(extension) == NULL) {
*error = kNoPageAction;
return scoped_refptr<ContentAction>();
}
return scoped_refptr<ContentAction>(new ShowPageAction);
}
virtual Type GetType() const OVERRIDE { return ACTION_SHOW_PAGE_ACTION; }
virtual void Apply(const std::string& extension_id,
const base::Time& extension_install_time,
ApplyInfo* apply_info) const OVERRIDE {
GetPageAction(apply_info->profile, extension_id)->DeclarativeShow(
ExtensionTabUtil::GetTabId(apply_info->tab));
apply_info->tab->NotifyNavigationStateChanged(
content::INVALIDATE_TYPE_PAGE_ACTIONS);
}
virtual void Revert(const std::string& extension_id,
const base::Time& extension_install_time,
ApplyInfo* apply_info) const OVERRIDE {
if (ExtensionAction* action =
GetPageAction(apply_info->profile, extension_id)) {
action->UndoDeclarativeShow(ExtensionTabUtil::GetTabId(apply_info->tab));
apply_info->tab->NotifyNavigationStateChanged(
content::INVALIDATE_TYPE_PAGE_ACTIONS);
}
}
private:
static ExtensionAction* GetPageAction(Profile* profile,
const std::string& extension_id) {
ExtensionService* service =
ExtensionSystem::Get(profile)->extension_service();
const Extension* extension = service->GetInstalledExtension(extension_id);
if (!extension)
return NULL;
return ExtensionActionManager::Get(profile)->GetPageAction(*extension);
}
virtual ~ShowPageAction() {}
DISALLOW_COPY_AND_ASSIGN(ShowPageAction);
};
struct ContentActionFactory {
typedef scoped_refptr<ContentAction>(*FactoryMethod)(
const Extension* ,
const base::DictionaryValue* ,
std::string* ,
bool* );
std::map<std::string, FactoryMethod> factory_methods;
ContentActionFactory() {
factory_methods[keys::kShowPageAction] =
&ShowPageAction::Create;
}
};
base::LazyInstance<ContentActionFactory>::Leaky
g_content_action_factory = LAZY_INSTANCE_INITIALIZER;
}
ContentAction::ContentAction() {}
ContentAction::~ContentAction() {}
scoped_refptr<ContentAction> ContentAction::Create(
const Extension* extension,
const base::Value& json_action,
std::string* error,
bool* bad_message) {
*error = "";
*bad_message = false;
const base::DictionaryValue* action_dict = NULL;
INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict));
std::string instance_type;
INPUT_FORMAT_VALIDATE(
action_dict->GetString(keys::kInstanceType, &instance_type));
ContentActionFactory& factory = g_content_action_factory.Get();
std::map<std::string, ContentActionFactory::FactoryMethod>::iterator
factory_method_iter = factory.factory_methods.find(instance_type);
if (factory_method_iter != factory.factory_methods.end())
return (*factory_method_iter->second)(
extension, action_dict, error, bad_message);
*error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str());
return scoped_refptr<ContentAction>();
}
}