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_empty()) { | |
107 web_contents->DownloadImage( | |
108 GURL(items[i].icon), | |
dcheng
2015/02/23 16:33:03
No GURL() here, since this is already a GURL.
pals
2015/02/24 05:25:59
Done. Now added a check for validity of the icon u
| |
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 |