| 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 |