OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_sidebar_api.h" | 5 #include "chrome/browser/extensions/extension_sidebar_api.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/string16.h" | 10 #include "base/string16.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "chrome/browser/extensions/extension_event_router.h" | 12 #include "chrome/browser/extensions/extension_event_router.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
14 #include "chrome/browser/extensions/extension_tabs_module.h" | 14 #include "chrome/browser/extensions/extension_tabs_module.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/sidebar/sidebar_container.h" | 16 #include "chrome/browser/sidebar/sidebar_container.h" |
17 #include "chrome/browser/sidebar/sidebar_manager.h" | 17 #include "chrome/browser/sidebar/sidebar_manager.h" |
18 #include "chrome/browser/tab_contents/tab_contents.h" | 18 #include "chrome/browser/tab_contents/tab_contents.h" |
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
20 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
21 #include "chrome/common/extensions/extension_constants.h" | 21 #include "chrome/common/extensions/extension_constants.h" |
22 #include "chrome/common/extensions/extension_error_utils.h" | 22 #include "chrome/common/extensions/extension_error_utils.h" |
| 23 #include "chrome/common/extensions/extension_sidebar_utils.h" |
23 #include "chrome/common/render_messages.h" | 24 #include "chrome/common/render_messages.h" |
24 #include "chrome/common/url_constants.h" | |
25 #include "ipc/ipc_message_utils.h" | 25 #include "ipc/ipc_message_utils.h" |
26 #include "third_party/skia/include/core/SkBitmap.h" | 26 #include "third_party/skia/include/core/SkBitmap.h" |
27 | 27 |
28 namespace { | 28 namespace { |
29 // Errors. | 29 // Errors. |
| 30 const char kNoSidebarError[] = |
| 31 "This extension has no sidebar specified."; |
30 const char kNoTabError[] = "No tab with id: *."; | 32 const char kNoTabError[] = "No tab with id: *."; |
31 const char kInvalidUrlError[] = "Invalid url: \"*\"."; | |
32 const char kNoCurrentWindowError[] = "No current browser window was found"; | 33 const char kNoCurrentWindowError[] = "No current browser window was found"; |
33 const char kNoDefaultTabError[] = "No default tab was found"; | 34 const char kNoDefaultTabError[] = "No default tab was found"; |
34 const char kInvalidExpandContextError[] = | 35 const char kInvalidExpandContextError[] = |
35 "Sidebar can be expanded only in response to an explicit user gesture"; | 36 "Sidebar can be expanded only in response to an explicit user gesture"; |
36 // Keys. | 37 // Keys. |
37 const char kBadgeTextKey[] = "text"; | 38 const char kBadgeTextKey[] = "text"; |
38 const char kImageDataKey[] = "imageData"; | 39 const char kImageDataKey[] = "imageData"; |
39 const char kStateKey[] = "state"; | 40 const char kStateKey[] = "state"; |
40 const char kTabIdKey[] = "tabId"; | 41 const char kTabIdKey[] = "tabId"; |
41 const char kTitleKey[] = "title"; | 42 const char kTitleKey[] = "title"; |
42 const char kUrlKey[] = "url"; | 43 const char kUrlKey[] = "url"; |
43 // Events. | 44 // Events. |
44 const char kOnStateChanged[] = "experimental.sidebar.onStateChanged"; | 45 const char kOnStateChanged[] = "experimental.sidebar.onStateChanged"; |
45 } // namespace | 46 } // namespace |
46 | 47 |
47 namespace extension_sidebar_constants { | 48 namespace extension_sidebar_constants { |
48 // Sidebar states. | 49 // Sidebar states. |
49 const char kActiveState[] = "active"; | 50 const char kActiveState[] = "active"; |
50 const char kHiddenState[] = "hidden"; | 51 const char kHiddenState[] = "hidden"; |
51 const char kShownState[] = "shown"; | 52 const char kShownState[] = "shown"; |
52 } | 53 } // namespace extension_sidebar_constants |
53 | |
54 static GURL ResolvePossiblyRelativeURL(const std::string& url_string, | |
55 const Extension* extension) { | |
56 GURL url = GURL(url_string); | |
57 if (!url.is_valid()) | |
58 url = extension->GetResourceURL(url_string); | |
59 | |
60 return url; | |
61 } | |
62 | |
63 static bool CanUseHost(const Extension* extension, | |
64 const GURL& url, | |
65 std::string* error) { | |
66 if (extension->HasHostPermission(url)) | |
67 return true; | |
68 | |
69 if (error) { | |
70 *error = ExtensionErrorUtils::FormatErrorMessage( | |
71 extension_manifest_errors::kCannotAccessPage, url.spec()); | |
72 } | |
73 | |
74 return false; | |
75 } | |
76 | |
77 | 54 |
78 // static | 55 // static |
79 void ExtensionSidebarEventRouter::OnStateChanged( | 56 void ExtensionSidebarEventRouter::OnStateChanged( |
80 Profile* profile, TabContents* tab, const std::string& content_id, | 57 Profile* profile, TabContents* tab, const std::string& content_id, |
81 const std::string& state) { | 58 const std::string& state) { |
82 int tab_id = ExtensionTabUtil::GetTabId(tab); | 59 int tab_id = ExtensionTabUtil::GetTabId(tab); |
83 DictionaryValue* details = new DictionaryValue; | 60 DictionaryValue* details = new DictionaryValue; |
84 details->Set(kTabIdKey, Value::CreateIntegerValue(tab_id)); | 61 details->Set(kTabIdKey, Value::CreateIntegerValue(tab_id)); |
85 details->Set(kStateKey, Value::CreateStringValue(state)); | 62 details->Set(kStateKey, Value::CreateStringValue(state)); |
86 | 63 |
87 ListValue args; | 64 ListValue args; |
88 args.Set(0, details); | 65 args.Set(0, details); |
89 std::string json_args; | 66 std::string json_args; |
90 base::JSONWriter::Write(&args, false, &json_args); | 67 base::JSONWriter::Write(&args, false, &json_args); |
91 | 68 |
92 const std::string& extension_id(content_id); | |
93 profile->GetExtensionEventRouter()->DispatchEventToExtension( | 69 profile->GetExtensionEventRouter()->DispatchEventToExtension( |
94 extension_id, kOnStateChanged, json_args, profile, GURL()); | 70 extension_sidebar_utils::GetExtensionIdByContentId(content_id), |
| 71 kOnStateChanged, json_args, profile, GURL()); |
95 } | 72 } |
96 | 73 |
97 | 74 |
98 // List is considered empty if it is actually empty or contains just one value, | 75 // List is considered empty if it is actually empty or contains just one value, |
99 // either 'null' or 'undefined'. | 76 // either 'null' or 'undefined'. |
100 static bool IsArgumentListEmpty(const ListValue* arguments) { | 77 static bool IsArgumentListEmpty(const ListValue* arguments) { |
101 if (arguments->empty()) | 78 if (arguments->empty()) |
102 return true; | 79 return true; |
103 if (arguments->GetSize() == 1) { | 80 if (arguments->GetSize() == 1) { |
104 Value* first_value = 0; | 81 Value* first_value = 0; |
105 if (!arguments->Get(0, &first_value)) | 82 if (!arguments->Get(0, &first_value)) |
106 return true; | 83 return true; |
107 if (first_value->GetType() == Value::TYPE_NULL) | 84 if (first_value->GetType() == Value::TYPE_NULL) |
108 return true; | 85 return true; |
109 } | 86 } |
110 return false; | 87 return false; |
111 } | 88 } |
112 | 89 |
113 bool SidebarFunction::RunImpl() { | 90 bool SidebarFunction::RunImpl() { |
| 91 if (!GetExtension()->sidebar_defaults()) { |
| 92 error_ = kNoSidebarError; |
| 93 return false; |
| 94 } |
| 95 |
114 if (!args_.get()) | 96 if (!args_.get()) |
115 return false; | 97 return false; |
116 | 98 |
117 DictionaryValue* details = NULL; | 99 DictionaryValue* details = NULL; |
118 DictionaryValue default_details; | 100 DictionaryValue default_details; |
119 if (IsArgumentListEmpty(args_.get())) { | 101 if (IsArgumentListEmpty(args_.get())) { |
120 details = &default_details; | 102 details = &default_details; |
121 } else { | 103 } else { |
122 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 104 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
123 } | 105 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 const DictionaryValue& details) { | 199 const DictionaryValue& details) { |
218 SidebarManager::GetInstance()->HideSidebar(tab, content_id); | 200 SidebarManager::GetInstance()->HideSidebar(tab, content_id); |
219 return true; | 201 return true; |
220 } | 202 } |
221 | 203 |
222 bool NavigateSidebarFunction::RunImpl(TabContents* tab, | 204 bool NavigateSidebarFunction::RunImpl(TabContents* tab, |
223 const std::string& content_id, | 205 const std::string& content_id, |
224 const DictionaryValue& details) { | 206 const DictionaryValue& details) { |
225 std::string url_string; | 207 std::string url_string; |
226 EXTENSION_FUNCTION_VALIDATE(details.GetString(kUrlKey, &url_string)); | 208 EXTENSION_FUNCTION_VALIDATE(details.GetString(kUrlKey, &url_string)); |
227 GURL url = ResolvePossiblyRelativeURL(url_string, GetExtension()); | 209 |
228 if (!url.is_valid()) { | 210 GURL url = extension_sidebar_utils::ResolveAndVerifyUrl( |
229 error_ = ExtensionErrorUtils::FormatErrorMessage(kInvalidUrlError, | 211 url_string, GetExtension(), &error_); |
230 url_string); | 212 if (!url.is_valid()) |
231 return false; | 213 return false; |
232 } | |
233 if (!url.SchemeIs(chrome::kExtensionScheme) && | |
234 !CanUseHost(GetExtension(), url, &error_)) { | |
235 return false; | |
236 } | |
237 // Disallow requests outside of the requesting extension view's extension. | |
238 if (url.SchemeIs(chrome::kExtensionScheme)) { | |
239 std::string extension_id(url.host()); | |
240 if (extension_id != GetExtension()->id()) | |
241 return false; | |
242 } | |
243 | 214 |
244 SidebarManager::GetInstance()->NavigateSidebar(tab, content_id, GURL(url)); | 215 SidebarManager::GetInstance()->NavigateSidebar(tab, content_id, url); |
245 return true; | 216 return true; |
246 } | 217 } |
247 | 218 |
248 bool SetBadgeTextSidebarFunction::RunImpl(TabContents* tab, | 219 bool SetBadgeTextSidebarFunction::RunImpl(TabContents* tab, |
249 const std::string& content_id, | 220 const std::string& content_id, |
250 const DictionaryValue& details) { | 221 const DictionaryValue& details) { |
251 string16 badge_text; | 222 string16 badge_text; |
252 EXTENSION_FUNCTION_VALIDATE(details.GetString(kBadgeTextKey, &badge_text)); | 223 EXTENSION_FUNCTION_VALIDATE(details.GetString(kBadgeTextKey, &badge_text)); |
253 SidebarManager::GetInstance()->SetSidebarBadgeText( | 224 SidebarManager::GetInstance()->SetSidebarBadgeText( |
254 tab, content_id, badge_text); | 225 tab, content_id, badge_text); |
(...skipping 22 matching lines...) Expand all Loading... |
277 SidebarManager::GetInstance()->SetSidebarTitle(tab, content_id, title); | 248 SidebarManager::GetInstance()->SetSidebarTitle(tab, content_id, title); |
278 return true; | 249 return true; |
279 } | 250 } |
280 | 251 |
281 bool ShowSidebarFunction::RunImpl(TabContents* tab, | 252 bool ShowSidebarFunction::RunImpl(TabContents* tab, |
282 const std::string& content_id, | 253 const std::string& content_id, |
283 const DictionaryValue& details) { | 254 const DictionaryValue& details) { |
284 SidebarManager::GetInstance()->ShowSidebar(tab, content_id); | 255 SidebarManager::GetInstance()->ShowSidebar(tab, content_id); |
285 return true; | 256 return true; |
286 } | 257 } |
OLD | NEW |