Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/renderer_context_menu/render_view_context_menu_base.h" | 5 #include "components/renderer_context_menu/render_view_context_menu_base.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "content/public/browser/render_frame_host.h" | 12 #include "content/public/browser/render_frame_host.h" |
| 13 #include "content/public/browser/render_process_host.h" | 13 #include "content/public/browser/render_process_host.h" |
| 14 #include "content/public/browser/render_view_host.h" | 14 #include "content/public/browser/render_view_host.h" |
| 15 #include "content/public/browser/render_widget_host_view.h" | 15 #include "content/public/browser/render_widget_host_view.h" |
| 16 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
| 17 #include "content/public/common/menu_item.h" | 17 #include "content/public/common/menu_item.h" |
| 18 #include "third_party/WebKit/public/web/WebContextMenuData.h" | 18 #include "third_party/WebKit/public/web/WebContextMenuData.h" |
| 19 #include "ui/gfx/image/image.h" | |
| 20 #include "ui/gfx/image/image_skia_operations.h" | |
| 19 | 21 |
| 20 using blink::WebContextMenuData; | 22 using blink::WebContextMenuData; |
| 21 using blink::WebString; | 23 using blink::WebString; |
| 22 using blink::WebURL; | 24 using blink::WebURL; |
| 23 using content::BrowserContext; | 25 using content::BrowserContext; |
| 24 using content::OpenURLParams; | 26 using content::OpenURLParams; |
| 25 using content::RenderFrameHost; | 27 using content::RenderFrameHost; |
| 26 using content::RenderViewHost; | 28 using content::RenderViewHost; |
| 27 using content::WebContents; | 29 using content::WebContents; |
| 28 | 30 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 59 if (items[i].type == content::MenuItem::SUBMENU) { | 61 if (items[i].type == content::MenuItem::SUBMENU) { |
| 60 if (IsCustomItemCheckedInternal(items[i].submenu, id)) | 62 if (IsCustomItemCheckedInternal(items[i].submenu, id)) |
| 61 return true; | 63 return true; |
| 62 } | 64 } |
| 63 } | 65 } |
| 64 return false; | 66 return false; |
| 65 } | 67 } |
| 66 | 68 |
| 67 const size_t kMaxCustomMenuDepth = 5; | 69 const size_t kMaxCustomMenuDepth = 5; |
| 68 const size_t kMaxCustomMenuTotalItems = 1000; | 70 const size_t kMaxCustomMenuTotalItems = 1000; |
| 71 const size_t kMenuItemIconSize = 16; | |
| 72 | |
| 73 void OnIconDownloaded(RenderViewContextMenuBase* menu, | |
| 74 int command_id, | |
| 75 int id, | |
| 76 int http_status_code, | |
| 77 const GURL& image_url, | |
| 78 const std::vector<SkBitmap>& bitmaps, | |
| 79 const std::vector<gfx::Size>& original_bitmap_sizes) { | |
| 80 if (bitmaps.empty()) | |
| 81 return; | |
| 82 gfx::ImageSkia icon = gfx::ImageSkia::CreateFrom1xBitmap(bitmaps[0]); | |
| 83 // Scale icon to a 16X16 size. | |
| 84 gfx::ImageSkia scaled_icon = | |
| 85 gfx::ImageSkiaOperations::CreateResizedImage( | |
| 86 icon, | |
| 87 skia::ImageOperations::RESIZE_BEST, | |
| 88 gfx::Size(kMenuItemIconSize, kMenuItemIconSize)); | |
| 89 if (menu) | |
| 90 menu->SetIcon(command_id, scaled_icon); | |
| 91 } | |
| 69 | 92 |
| 70 void AddCustomItemsToMenu(const std::vector<content::MenuItem>& items, | 93 void AddCustomItemsToMenu(const std::vector<content::MenuItem>& items, |
| 71 size_t depth, | 94 size_t depth, |
| 72 size_t* total_items, | 95 size_t* total_items, |
| 73 ui::SimpleMenuModel::Delegate* delegate, | 96 ui::SimpleMenuModel::Delegate* delegate, |
| 74 ui::SimpleMenuModel* menu_model) { | 97 ui::SimpleMenuModel* menu_model, |
| 98 content::WebContents* web_contents) { | |
| 75 if (depth > kMaxCustomMenuDepth) { | 99 if (depth > kMaxCustomMenuDepth) { |
| 76 LOG(ERROR) << "Custom menu too deeply nested."; | 100 LOG(ERROR) << "Custom menu too deeply nested."; |
| 77 return; | 101 return; |
| 78 } | 102 } |
| 79 for (size_t i = 0; i < items.size(); ++i) { | 103 for (size_t i = 0; i < items.size(); ++i) { |
| 80 int command_id = RenderViewContextMenuBase::ConvertToContentCustomCommandId( | 104 int command_id = RenderViewContextMenuBase::ConvertToContentCustomCommandId( |
| 81 items[i].action); | 105 items[i].action); |
| 106 if (items[i].icon.is_valid()) { | |
|
jochen (gone - plz use gerrit)
2015/02/24 10:26:57
i'm still concerned what happens if you specify fo
| |
| 107 web_contents->DownloadImage( | |
| 108 items[i].icon, | |
| 109 true, // is_favicon | |
| 110 0, // unlimited | |
| 111 base::Bind(OnIconDownloaded, | |
| 112 base::Unretained( | |
| 113 static_cast<RenderViewContextMenuBase*>(delegate)), | |
| 114 command_id)); | |
| 115 } | |
| 116 | |
| 82 if (!RenderViewContextMenuBase::IsContentCustomCommandId(command_id)) { | 117 if (!RenderViewContextMenuBase::IsContentCustomCommandId(command_id)) { |
| 83 LOG(ERROR) << "Custom menu action value out of range."; | 118 LOG(ERROR) << "Custom menu action value out of range."; |
| 84 return; | 119 return; |
| 85 } | 120 } |
| 86 if (*total_items >= kMaxCustomMenuTotalItems) { | 121 if (*total_items >= kMaxCustomMenuTotalItems) { |
| 87 LOG(ERROR) << "Custom menu too large (too many items)."; | 122 LOG(ERROR) << "Custom menu too large (too many items)."; |
| 88 return; | 123 return; |
| 89 } | 124 } |
| 90 (*total_items)++; | 125 (*total_items)++; |
| 91 switch (items[i].type) { | 126 switch (items[i].type) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 104 case content::MenuItem::GROUP: | 139 case content::MenuItem::GROUP: |
| 105 // TODO(viettrungluu): I don't know what this is supposed to do. | 140 // TODO(viettrungluu): I don't know what this is supposed to do. |
| 106 NOTREACHED(); | 141 NOTREACHED(); |
| 107 break; | 142 break; |
| 108 case content::MenuItem::SEPARATOR: | 143 case content::MenuItem::SEPARATOR: |
| 109 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); | 144 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); |
| 110 break; | 145 break; |
| 111 case content::MenuItem::SUBMENU: { | 146 case content::MenuItem::SUBMENU: { |
| 112 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate); | 147 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate); |
| 113 AddCustomItemsToMenu(items[i].submenu, depth + 1, total_items, delegate, | 148 AddCustomItemsToMenu(items[i].submenu, depth + 1, total_items, delegate, |
| 114 submenu); | 149 submenu, web_contents); |
| 115 menu_model->AddSubMenu( | 150 menu_model->AddSubMenu( |
| 116 RenderViewContextMenuBase::ConvertToContentCustomCommandId( | 151 RenderViewContextMenuBase::ConvertToContentCustomCommandId( |
| 117 items[i].action), | 152 items[i].action), |
| 118 items[i].label, | 153 items[i].label, |
| 119 submenu); | 154 submenu); |
| 120 break; | 155 break; |
| 121 } | 156 } |
| 122 default: | 157 default: |
| 123 NOTREACHED(); | 158 NOTREACHED(); |
| 124 break; | 159 break; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 void RenderViewContextMenuBase::AddSeparator() { | 243 void RenderViewContextMenuBase::AddSeparator() { |
| 209 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); | 244 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); |
| 210 } | 245 } |
| 211 | 246 |
| 212 void RenderViewContextMenuBase::AddSubMenu(int command_id, | 247 void RenderViewContextMenuBase::AddSubMenu(int command_id, |
| 213 const base::string16& label, | 248 const base::string16& label, |
| 214 ui::MenuModel* model) { | 249 ui::MenuModel* model) { |
| 215 menu_model_.AddSubMenu(command_id, label, model); | 250 menu_model_.AddSubMenu(command_id, label, model); |
| 216 } | 251 } |
| 217 | 252 |
| 253 void RenderViewContextMenuBase::SetIcon(int command_id, | |
| 254 const gfx::ImageSkia& icon) { | |
| 255 if (toolkit_delegate_) | |
| 256 toolkit_delegate_->SetIcon(command_id, icon); | |
| 257 } | |
| 258 | |
| 218 void RenderViewContextMenuBase::UpdateMenuItem(int command_id, | 259 void RenderViewContextMenuBase::UpdateMenuItem(int command_id, |
| 219 bool enabled, | 260 bool enabled, |
| 220 bool hidden, | 261 bool hidden, |
| 221 const base::string16& label) { | 262 const base::string16& label) { |
| 222 if (toolkit_delegate_) { | 263 if (toolkit_delegate_) { |
| 223 toolkit_delegate_->UpdateMenuItem(command_id, | 264 toolkit_delegate_->UpdateMenuItem(command_id, |
| 224 enabled, | 265 enabled, |
| 225 hidden, | 266 hidden, |
| 226 label); | 267 label); |
| 227 } | 268 } |
| 228 } | 269 } |
| 229 | 270 |
| 230 RenderViewHost* RenderViewContextMenuBase::GetRenderViewHost() const { | 271 RenderViewHost* RenderViewContextMenuBase::GetRenderViewHost() const { |
| 231 return source_web_contents_->GetRenderViewHost(); | 272 return source_web_contents_->GetRenderViewHost(); |
| 232 } | 273 } |
| 233 | 274 |
| 234 WebContents* RenderViewContextMenuBase::GetWebContents() const { | 275 WebContents* RenderViewContextMenuBase::GetWebContents() const { |
| 235 return source_web_contents_; | 276 return source_web_contents_; |
| 236 } | 277 } |
| 237 | 278 |
| 238 BrowserContext* RenderViewContextMenuBase::GetBrowserContext() const { | 279 BrowserContext* RenderViewContextMenuBase::GetBrowserContext() const { |
| 239 return browser_context_; | 280 return browser_context_; |
| 240 } | 281 } |
| 241 | 282 |
| 242 bool RenderViewContextMenuBase::AppendCustomItems() { | 283 bool RenderViewContextMenuBase::AppendCustomItems() { |
| 243 size_t total_items = 0; | 284 size_t total_items = 0; |
| 244 AddCustomItemsToMenu(params_.custom_items, 0, &total_items, this, | 285 AddCustomItemsToMenu(params_.custom_items, 0, &total_items, this, |
| 245 &menu_model_); | 286 &menu_model_, source_web_contents_); |
| 246 return total_items > 0; | 287 return total_items > 0; |
| 247 } | 288 } |
| 248 | 289 |
| 249 bool RenderViewContextMenuBase::IsCommandIdKnown( | 290 bool RenderViewContextMenuBase::IsCommandIdKnown( |
| 250 int id, | 291 int id, |
| 251 bool* enabled) const { | 292 bool* enabled) const { |
| 252 // If this command is is added by one of our observers, we dispatch | 293 // If this command is is added by one of our observers, we dispatch |
| 253 // it to the observer. | 294 // it to the observer. |
| 254 ObserverListBase<RenderViewContextMenuObserver>::Iterator it(observers_); | 295 ObserverListBase<RenderViewContextMenuObserver>::Iterator it(observers_); |
| 255 RenderViewContextMenuObserver* observer; | 296 RenderViewContextMenuObserver* observer; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 } | 421 } |
| 381 | 422 |
| 382 bool RenderViewContextMenuBase::IsCustomItemChecked(int id) const { | 423 bool RenderViewContextMenuBase::IsCustomItemChecked(int id) const { |
| 383 return IsCustomItemCheckedInternal(params_.custom_items, id); | 424 return IsCustomItemCheckedInternal(params_.custom_items, id); |
| 384 } | 425 } |
| 385 | 426 |
| 386 bool RenderViewContextMenuBase::IsCustomItemEnabled(int id) const { | 427 bool RenderViewContextMenuBase::IsCustomItemEnabled(int id) const { |
| 387 return IsCustomItemEnabledInternal(params_.custom_items, id); | 428 return IsCustomItemEnabledInternal(params_.custom_items, id); |
| 388 } | 429 } |
| 389 | 430 |
| OLD | NEW |