blob: c6b1a3357cecf7f5107856aed33443269078e430 [file] [log] [blame]
// 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/common/extensions/api/input_ime/input_components_handler.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
namespace extensions {
namespace keys = manifest_keys;
namespace errors = manifest_errors;
InputComponentInfo::InputComponentInfo()
: type(INPUT_COMPONENT_TYPE_NONE),
shortcut_alt(false),
shortcut_ctrl(false),
shortcut_shift(false) {
}
InputComponentInfo::~InputComponentInfo() {}
InputComponents::InputComponents() {}
InputComponents::~InputComponents() {}
// static
const std::vector<InputComponentInfo>* InputComponents::GetInputComponents(
const Extension* extension) {
InputComponents* info = static_cast<InputComponents*>(
extension->GetManifestData(keys::kInputComponents));
return info ? &info->input_components : NULL;
}
InputComponentsHandler::InputComponentsHandler() {
}
InputComponentsHandler::~InputComponentsHandler() {
}
bool InputComponentsHandler::Parse(Extension* extension,
string16* error) {
scoped_ptr<InputComponents> info(new InputComponents);
const base::ListValue* list_value = NULL;
if (!extension->manifest()->GetList(keys::kInputComponents, &list_value)) {
*error = ASCIIToUTF16(errors::kInvalidInputComponents);
return false;
}
for (size_t i = 0; i < list_value->GetSize(); ++i) {
const base::DictionaryValue* module_value = NULL;
std::string name_str;
InputComponentType type;
std::string id_str;
std::string description_str;
std::set<std::string> languages;
std::set<std::string> layouts;
std::string shortcut_keycode_str;
bool shortcut_alt = false;
bool shortcut_ctrl = false;
bool shortcut_shift = false;
if (!list_value->GetDictionary(i, &module_value)) {
*error = ASCIIToUTF16(errors::kInvalidInputComponents);
return false;
}
// Get input_components[i].name.
if (!module_value->GetString(keys::kName, &name_str)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentName,
base::IntToString(i));
return false;
}
// Get input_components[i].type.
std::string type_str;
if (module_value->GetString(keys::kType, &type_str)) {
if (type_str == "ime") {
type = INPUT_COMPONENT_TYPE_IME;
} else {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentType,
base::IntToString(i));
return false;
}
} else {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentType,
base::IntToString(i));
return false;
}
// Get input_components[i].id.
if (!module_value->GetString(keys::kId, &id_str)) {
id_str = "";
}
// Get input_components[i].description.
if (!module_value->GetString(keys::kDescription, &description_str)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentDescription,
base::IntToString(i));
return false;
}
// Get input_components[i].language.
// Both string and list of string are allowed to be compatibile with old
// input_ime manifest specification.
const base::Value* language_value = NULL;
if (module_value->Get(keys::kLanguage, &language_value)) {
if (language_value->GetType() == base::Value::TYPE_STRING) {
std::string language_str;
language_value->GetAsString(&language_str);
languages.insert(language_str);
} else if (language_value->GetType() == base::Value::TYPE_LIST) {
const base::ListValue* language_list = NULL;
language_value->GetAsList(&language_list);
for (size_t j = 0; j < language_list->GetSize(); ++j) {
std::string language_str;
if (language_list->GetString(j, &language_str))
languages.insert(language_str);
}
}
}
// Get input_components[i].layouts.
const base::ListValue* layouts_value = NULL;
if (module_value->GetList(keys::kLayouts, &layouts_value)) {
for (size_t j = 0; j < layouts_value->GetSize(); ++j) {
std::string layout_name_str;
if (!layouts_value->GetString(j, &layout_name_str)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentLayoutName,
base::IntToString(i), base::IntToString(j));
return false;
}
layouts.insert(layout_name_str);
}
}
if (module_value->HasKey(keys::kShortcutKey)) {
const DictionaryValue* shortcut_value = NULL;
if (!module_value->GetDictionary(keys::kShortcutKey,
&shortcut_value)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentShortcutKey,
base::IntToString(i));
return false;
}
// Get input_components[i].shortcut_keycode.
if (!shortcut_value->GetString(keys::kKeycode, &shortcut_keycode_str)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidInputComponentShortcutKeycode,
base::IntToString(i));
return false;
}
// Get input_components[i].shortcut_alt.
if (!shortcut_value->GetBoolean(keys::kAltKey, &shortcut_alt)) {
shortcut_alt = false;
}
// Get input_components[i].shortcut_ctrl.
if (!shortcut_value->GetBoolean(keys::kCtrlKey, &shortcut_ctrl)) {
shortcut_ctrl = false;
}
// Get input_components[i].shortcut_shift.
if (!shortcut_value->GetBoolean(keys::kShiftKey, &shortcut_shift)) {
shortcut_shift = false;
}
}
info->input_components.push_back(InputComponentInfo());
info->input_components.back().name = name_str;
info->input_components.back().type = type;
info->input_components.back().id = id_str;
info->input_components.back().description = description_str;
info->input_components.back().languages = languages;
info->input_components.back().layouts.insert(layouts.begin(),
layouts.end());
info->input_components.back().shortcut_keycode = shortcut_keycode_str;
info->input_components.back().shortcut_alt = shortcut_alt;
info->input_components.back().shortcut_ctrl = shortcut_ctrl;
info->input_components.back().shortcut_shift = shortcut_shift;
info->input_components.back().options_page_url =
extensions::ManifestURL::GetOptionsPage(extension);
}
extension->SetManifestData(keys::kInputComponents, info.release());
return true;
}
const std::vector<std::string> InputComponentsHandler::Keys() const {
return SingleKey(keys::kInputComponents);
}
} // namespace extensions