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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
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/common/extensions/manifest_handler_helpers.h"
6
7 #include "base/logging.h"
8 #include "base/string_number_conversions.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/common/extensions/api/extension_action/action_info.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/extensions/extension_icon_set.h"
14 #include "chrome/common/extensions/extension_manifest_constants.h"
15 #include "extensions/common/error_utils.h"
16
17 namespace errors = extension_manifest_errors;
18 namespace keys = extension_manifest_keys;
19
20 namespace extensions {
21 namespace manifest_handler_helpers {
22
23 bool NormalizeAndValidatePath(std::string* path) {
24 size_t first_non_slash = path->find_first_not_of('/');
25 if (first_non_slash == std::string::npos) {
26 *path = "";
27 return false;
28 }
29
30 *path = path->substr(first_non_slash);
31 return true;
32 }
33
34 bool LoadIconsFromDictionary(const base::DictionaryValue* icons_value,
35 const int* icon_sizes,
36 size_t num_icon_sizes,
37 ExtensionIconSet* icons,
38 string16* error) {
39 DCHECK(icons);
40 for (size_t i = 0; i < num_icon_sizes; ++i) {
41 std::string key = base::IntToString(icon_sizes[i]);
42 if (icons_value->HasKey(key)) {
43 std::string icon_path;
44 if (!icons_value->GetString(key, &icon_path)) {
45 *error = ErrorUtils::FormatErrorMessageUTF16(
46 errors::kInvalidIconPath, key);
47 return false;
48 }
49
50 if (!NormalizeAndValidatePath(&icon_path)) {
51 *error = ErrorUtils::FormatErrorMessageUTF16(
52 errors::kInvalidIconPath, key);
53 return false;
54 }
55
56 icons->Add(icon_sizes[i], icon_path);
57 }
58 }
59 return true;
60 }
61
62 scoped_ptr<ActionInfo> LoadActionInfo(
63 const Extension* extension,
64 const base::DictionaryValue* extension_action,
65 string16* error) {
66 scoped_ptr<ActionInfo> result(new ActionInfo());
67
68 if (extension->manifest_version() == 1) {
69 // kPageActionIcons is obsolete, and used by very few extensions. Continue
70 // loading it, but only take the first icon as the default_icon path.
71 const ListValue* icons = NULL;
72 if (extension_action->HasKey(keys::kPageActionIcons) &&
73 extension_action->GetList(keys::kPageActionIcons, &icons)) {
74 for (ListValue::const_iterator iter = icons->begin();
75 iter != icons->end(); ++iter) {
76 std::string path;
77 if (!(*iter)->GetAsString(&path) ||
78 !manifest_handler_helpers::NormalizeAndValidatePath(&path)) {
79 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
80 return scoped_ptr<ActionInfo>();
81 }
82
83 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path);
84 break;
85 }
86 }
87
88 std::string id;
89 if (extension_action->HasKey(keys::kPageActionId)) {
90 if (!extension_action->GetString(keys::kPageActionId, &id)) {
91 *error = ASCIIToUTF16(errors::kInvalidPageActionId);
92 return scoped_ptr<ActionInfo>();
93 }
94 result->id = id;
95 }
96 }
97
98 // Read the page action |default_icon| (optional).
99 // The |default_icon| value can be either dictionary {icon size -> icon path}
100 // or non empty string value.
101 if (extension_action->HasKey(keys::kPageActionDefaultIcon)) {
102 const DictionaryValue* icons_value = NULL;
103 std::string default_icon;
104 if (extension_action->GetDictionary(keys::kPageActionDefaultIcon,
105 &icons_value)) {
106 if (!manifest_handler_helpers::LoadIconsFromDictionary(
107 icons_value,
108 extension_misc::kExtensionActionIconSizes,
109 extension_misc::kNumExtensionActionIconSizes,
110 &result->default_icon,
111 error)) {
112 return scoped_ptr<ActionInfo>();
113 }
114 } else if (extension_action->GetString(keys::kPageActionDefaultIcon,
115 &default_icon) &&
116 manifest_handler_helpers::NormalizeAndValidatePath(
117 &default_icon)) {
118 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION,
119 default_icon);
120 } else {
121 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
122 return scoped_ptr<ActionInfo>();
123 }
124 }
125
126 // Read the page action title from |default_title| if present, |name| if not
127 // (both optional).
128 if (extension_action->HasKey(keys::kPageActionDefaultTitle)) {
129 if (!extension_action->GetString(keys::kPageActionDefaultTitle,
130 &result->default_title)) {
131 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
132 return scoped_ptr<ActionInfo>();
133 }
134 } else if (extension->manifest_version() == 1 &&
135 extension_action->HasKey(keys::kName)) {
136 if (!extension_action->GetString(keys::kName, &result->default_title)) {
137 *error = ASCIIToUTF16(errors::kInvalidPageActionName);
138 return scoped_ptr<ActionInfo>();
139 }
140 }
141
142 // Read the action's |popup| (optional).
143 const char* popup_key = NULL;
144 if (extension_action->HasKey(keys::kPageActionDefaultPopup))
145 popup_key = keys::kPageActionDefaultPopup;
146
147 if (extension->manifest_version() == 1 &&
148 extension_action->HasKey(keys::kPageActionPopup)) {
149 if (popup_key) {
150 *error = ErrorUtils::FormatErrorMessageUTF16(
151 errors::kInvalidPageActionOldAndNewKeys,
152 keys::kPageActionDefaultPopup,
153 keys::kPageActionPopup);
154 return scoped_ptr<ActionInfo>();
155 }
156 popup_key = keys::kPageActionPopup;
157 }
158
159 if (popup_key) {
160 const DictionaryValue* popup = NULL;
161 std::string url_str;
162
163 if (extension_action->GetString(popup_key, &url_str)) {
164 // On success, |url_str| is set. Nothing else to do.
165 } else if (extension->manifest_version() == 1 &&
166 extension_action->GetDictionary(popup_key, &popup)) {
167 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) {
168 *error = ErrorUtils::FormatErrorMessageUTF16(
169 errors::kInvalidPageActionPopupPath, "<missing>");
170 return scoped_ptr<ActionInfo>();
171 }
172 } else {
173 *error = ASCIIToUTF16(errors::kInvalidPageActionPopup);
174 return scoped_ptr<ActionInfo>();
175 }
176
177 if (!url_str.empty()) {
178 // An empty string is treated as having no popup.
179 result->default_popup_url = Extension::GetResourceURL(extension->url(),
180 url_str);
181 if (!result->default_popup_url.is_valid()) {
182 *error = ErrorUtils::FormatErrorMessageUTF16(
183 errors::kInvalidPageActionPopupPath, url_str);
184 return scoped_ptr<ActionInfo>();
185 }
186 } else {
187 DCHECK(result->default_popup_url.is_empty())
188 << "Shouldn't be possible for the popup to be set.";
189 }
190 }
191
192 return result.Pass();
193 }
194
195
196 } // namespace extensions
197 } // namespace manifest_handler_extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698