Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5501)

Unified Diff: chrome/common/extensions/manifest_handler_helpers.cc

Issue 11588004: Move ScriptBadge, ActionInfo out of Extension; preparation for BrowserAction (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Latest master for CQ Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/manifest_handler_helpers.cc
diff --git a/chrome/common/extensions/manifest_handler_helpers.cc b/chrome/common/extensions/manifest_handler_helpers.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fdcd5afd19372756ab4e2bf30f790e75bc173067
--- /dev/null
+++ b/chrome/common/extensions/manifest_handler_helpers.cc
@@ -0,0 +1,197 @@
+// 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/manifest_handler_helpers.h"
+
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/extensions/api/extension_action/action_info.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_icon_set.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "extensions/common/error_utils.h"
+
+namespace errors = extension_manifest_errors;
+namespace keys = extension_manifest_keys;
+
+namespace extensions {
+namespace manifest_handler_helpers {
+
+bool NormalizeAndValidatePath(std::string* path) {
+ size_t first_non_slash = path->find_first_not_of('/');
+ if (first_non_slash == std::string::npos) {
+ *path = "";
+ return false;
+ }
+
+ *path = path->substr(first_non_slash);
+ return true;
+}
+
+bool LoadIconsFromDictionary(const base::DictionaryValue* icons_value,
+ const int* icon_sizes,
+ size_t num_icon_sizes,
+ ExtensionIconSet* icons,
+ string16* error) {
+ DCHECK(icons);
+ for (size_t i = 0; i < num_icon_sizes; ++i) {
+ std::string key = base::IntToString(icon_sizes[i]);
+ if (icons_value->HasKey(key)) {
+ std::string icon_path;
+ if (!icons_value->GetString(key, &icon_path)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidIconPath, key);
+ return false;
+ }
+
+ if (!NormalizeAndValidatePath(&icon_path)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidIconPath, key);
+ return false;
+ }
+
+ icons->Add(icon_sizes[i], icon_path);
+ }
+ }
+ return true;
+}
+
+scoped_ptr<ActionInfo> LoadActionInfo(
+ const Extension* extension,
+ const base::DictionaryValue* extension_action,
+ string16* error) {
+ scoped_ptr<ActionInfo> result(new ActionInfo());
+
+ if (extension->manifest_version() == 1) {
+ // kPageActionIcons is obsolete, and used by very few extensions. Continue
+ // loading it, but only take the first icon as the default_icon path.
+ const ListValue* icons = NULL;
+ if (extension_action->HasKey(keys::kPageActionIcons) &&
+ extension_action->GetList(keys::kPageActionIcons, &icons)) {
+ for (ListValue::const_iterator iter = icons->begin();
+ iter != icons->end(); ++iter) {
+ std::string path;
+ if (!(*iter)->GetAsString(&path) ||
+ !manifest_handler_helpers::NormalizeAndValidatePath(&path)) {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
+ return scoped_ptr<ActionInfo>();
+ }
+
+ result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path);
+ break;
+ }
+ }
+
+ std::string id;
+ if (extension_action->HasKey(keys::kPageActionId)) {
+ if (!extension_action->GetString(keys::kPageActionId, &id)) {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionId);
+ return scoped_ptr<ActionInfo>();
+ }
+ result->id = id;
+ }
+ }
+
+ // Read the page action |default_icon| (optional).
+ // The |default_icon| value can be either dictionary {icon size -> icon path}
+ // or non empty string value.
+ if (extension_action->HasKey(keys::kPageActionDefaultIcon)) {
+ const DictionaryValue* icons_value = NULL;
+ std::string default_icon;
+ if (extension_action->GetDictionary(keys::kPageActionDefaultIcon,
+ &icons_value)) {
+ if (!manifest_handler_helpers::LoadIconsFromDictionary(
+ icons_value,
+ extension_misc::kExtensionActionIconSizes,
+ extension_misc::kNumExtensionActionIconSizes,
+ &result->default_icon,
+ error)) {
+ return scoped_ptr<ActionInfo>();
+ }
+ } else if (extension_action->GetString(keys::kPageActionDefaultIcon,
+ &default_icon) &&
+ manifest_handler_helpers::NormalizeAndValidatePath(
+ &default_icon)) {
+ result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION,
+ default_icon);
+ } else {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
+ return scoped_ptr<ActionInfo>();
+ }
+ }
+
+ // Read the page action title from |default_title| if present, |name| if not
+ // (both optional).
+ if (extension_action->HasKey(keys::kPageActionDefaultTitle)) {
+ if (!extension_action->GetString(keys::kPageActionDefaultTitle,
+ &result->default_title)) {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
+ return scoped_ptr<ActionInfo>();
+ }
+ } else if (extension->manifest_version() == 1 &&
+ extension_action->HasKey(keys::kName)) {
+ if (!extension_action->GetString(keys::kName, &result->default_title)) {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionName);
+ return scoped_ptr<ActionInfo>();
+ }
+ }
+
+ // Read the action's |popup| (optional).
+ const char* popup_key = NULL;
+ if (extension_action->HasKey(keys::kPageActionDefaultPopup))
+ popup_key = keys::kPageActionDefaultPopup;
+
+ if (extension->manifest_version() == 1 &&
+ extension_action->HasKey(keys::kPageActionPopup)) {
+ if (popup_key) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidPageActionOldAndNewKeys,
+ keys::kPageActionDefaultPopup,
+ keys::kPageActionPopup);
+ return scoped_ptr<ActionInfo>();
+ }
+ popup_key = keys::kPageActionPopup;
+ }
+
+ if (popup_key) {
+ const DictionaryValue* popup = NULL;
+ std::string url_str;
+
+ if (extension_action->GetString(popup_key, &url_str)) {
+ // On success, |url_str| is set. Nothing else to do.
+ } else if (extension->manifest_version() == 1 &&
+ extension_action->GetDictionary(popup_key, &popup)) {
+ if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidPageActionPopupPath, "<missing>");
+ return scoped_ptr<ActionInfo>();
+ }
+ } else {
+ *error = ASCIIToUTF16(errors::kInvalidPageActionPopup);
+ return scoped_ptr<ActionInfo>();
+ }
+
+ if (!url_str.empty()) {
+ // An empty string is treated as having no popup.
+ result->default_popup_url = Extension::GetResourceURL(extension->url(),
+ url_str);
+ if (!result->default_popup_url.is_valid()) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidPageActionPopupPath, url_str);
+ return scoped_ptr<ActionInfo>();
+ }
+ } else {
+ DCHECK(result->default_popup_url.is_empty())
+ << "Shouldn't be possible for the popup to be set.";
+ }
+ }
+
+ return result.Pass();
+}
+
+
+} // namespace extensions
+} // namespace manifest_handler_extensions

Powered by Google App Engine
This is Rietveld 408576698