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

Side by Side Diff: chrome/browser/tab_contents/render_view_context_menu.cc

Issue 6749021: Added new fileBrowserPrivate and fileHandler extension APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <algorithm> 5 #include <algorithm>
6 #include <set> 6 #include <set>
7 7
8 #include "chrome/browser/tab_contents/render_view_context_menu.h" 8 #include "chrome/browser/tab_contents/render_view_context_menu.h"
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 18 matching lines...) Expand all
29 #include "chrome/browser/page_info_window.h" 29 #include "chrome/browser/page_info_window.h"
30 #include "chrome/browser/platform_util.h" 30 #include "chrome/browser/platform_util.h"
31 #include "chrome/browser/prefs/pref_member.h" 31 #include "chrome/browser/prefs/pref_member.h"
32 #include "chrome/browser/prefs/pref_service.h" 32 #include "chrome/browser/prefs/pref_service.h"
33 #include "chrome/browser/printing/print_preview_tab_controller.h" 33 #include "chrome/browser/printing/print_preview_tab_controller.h"
34 #include "chrome/browser/profiles/profile.h" 34 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/search_engines/template_url.h" 35 #include "chrome/browser/search_engines/template_url.h"
36 #include "chrome/browser/search_engines/template_url_model.h" 36 #include "chrome/browser/search_engines/template_url_model.h"
37 #include "chrome/browser/spellcheck_host.h" 37 #include "chrome/browser/spellcheck_host.h"
38 #include "chrome/browser/spellchecker_platform_engine.h" 38 #include "chrome/browser/spellchecker_platform_engine.h"
39 #include "chrome/browser/tab_contents/context_menu_utils.h"
39 #include "chrome/browser/translate/translate_prefs.h" 40 #include "chrome/browser/translate/translate_prefs.h"
40 #include "chrome/browser/translate/translate_manager.h" 41 #include "chrome/browser/translate/translate_manager.h"
41 #include "chrome/common/chrome_constants.h" 42 #include "chrome/common/chrome_constants.h"
42 #include "chrome/common/chrome_switches.h" 43 #include "chrome/common/chrome_switches.h"
43 #include "chrome/common/content_restriction.h" 44 #include "chrome/common/content_restriction.h"
44 #include "chrome/common/pref_names.h" 45 #include "chrome/common/pref_names.h"
45 #include "chrome/common/print_messages.h" 46 #include "chrome/common/print_messages.h"
46 #include "chrome/common/url_constants.h" 47 #include "chrome/common/url_constants.h"
47 #include "content/browser/child_process_security_policy.h" 48 #include "content/browser/child_process_security_policy.h"
48 #include "content/browser/renderer_host/render_view_host.h" 49 #include "content/browser/renderer_host/render_view_host.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 RenderViewContextMenu::~RenderViewContextMenu() { 190 RenderViewContextMenu::~RenderViewContextMenu() {
190 } 191 }
191 192
192 // Menu construction functions ------------------------------------------------- 193 // Menu construction functions -------------------------------------------------
193 194
194 void RenderViewContextMenu::Init() { 195 void RenderViewContextMenu::Init() {
195 InitMenu(); 196 InitMenu();
196 PlatformInit(); 197 PlatformInit();
197 } 198 }
198 199
199 static bool ExtensionContextMatch(const ContextMenuParams& params,
200 ExtensionMenuItem::ContextList contexts) {
201 bool has_link = !params.link_url.is_empty();
202 bool has_selection = !params.selection_text.empty();
203 bool in_frame = !params.frame_url.is_empty();
204
205 if (contexts.Contains(ExtensionMenuItem::ALL) ||
206 (has_selection && contexts.Contains(ExtensionMenuItem::SELECTION)) ||
207 (has_link && contexts.Contains(ExtensionMenuItem::LINK)) ||
208 (params.is_editable && contexts.Contains(ExtensionMenuItem::EDITABLE)) ||
209 (in_frame && contexts.Contains(ExtensionMenuItem::FRAME))) {
210 return true;
211 }
212
213 switch (params.media_type) {
214 case WebContextMenuData::MediaTypeImage:
215 return contexts.Contains(ExtensionMenuItem::IMAGE);
216
217 case WebContextMenuData::MediaTypeVideo:
218 return contexts.Contains(ExtensionMenuItem::VIDEO);
219
220 case WebContextMenuData::MediaTypeAudio:
221 return contexts.Contains(ExtensionMenuItem::AUDIO);
222
223 default:
224 break;
225 }
226
227 // PAGE is the least specific context, so we only examine that if none of the
228 // other contexts apply (except for FRAME, which is included in PAGE for
229 // backwards compatibility).
230 if (!has_link && !has_selection && !params.is_editable &&
231 params.media_type == WebContextMenuData::MediaTypeNone &&
232 contexts.Contains(ExtensionMenuItem::PAGE))
233 return true;
234
235 return false;
236 }
237
238 static bool ExtensionPatternMatch(const ExtensionExtent& patterns,
239 const GURL& url) {
240 // No patterns means no restriction, so that implicitly matches.
241 if (patterns.is_empty())
242 return true;
243 return patterns.ContainsURL(url);
244 }
245
246 static const GURL& GetDocumentURL(const ContextMenuParams& params) {
247 return params.frame_url.is_empty() ? params.page_url : params.frame_url;
248 }
249
250 // Given a list of items, returns the ones that match given the contents
251 // of |params| and the profile.
252 static ExtensionMenuItem::List GetRelevantExtensionItems(
253 const ExtensionMenuItem::List& items,
254 const ContextMenuParams& params,
255 Profile* profile,
256 bool can_cross_incognito) {
257 ExtensionMenuItem::List result;
258 for (ExtensionMenuItem::List::const_iterator i = items.begin();
259 i != items.end(); ++i) {
260 const ExtensionMenuItem* item = *i;
261
262 if (!ExtensionContextMatch(params, item->contexts()))
263 continue;
264
265 const GURL& document_url = GetDocumentURL(params);
266 if (!ExtensionPatternMatch(item->document_url_patterns(), document_url))
267 continue;
268
269 const GURL& target_url =
270 params.src_url.is_empty() ? params.link_url : params.src_url;
271 if (!ExtensionPatternMatch(item->target_url_patterns(), target_url))
272 continue;
273
274 if (item->id().profile == profile || can_cross_incognito)
275 result.push_back(*i);
276 }
277 return result;
278 }
279
280 void RenderViewContextMenu::AppendExtensionItems( 200 void RenderViewContextMenu::AppendExtensionItems(
281 const std::string& extension_id, int* index) { 201 const std::string& extension_id, int* index) {
282 ExtensionService* service = profile_->GetExtensionService(); 202 ExtensionService* service = profile_->GetExtensionService();
283 ExtensionMenuManager* manager = service->menu_manager(); 203 ExtensionMenuManager* manager = service->menu_manager();
284 const Extension* extension = service->GetExtensionById(extension_id, false); 204 const Extension* extension = service->GetExtensionById(extension_id, false);
285 DCHECK_GE(*index, 0); 205 DCHECK_GE(*index, 0);
286 int max_index = 206 int max_index =
287 IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST - IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST; 207 IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST - IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST;
288 if (!extension || *index >= max_index) 208 if (!extension || *index >= max_index)
289 return; 209 return;
290 210
291 // Find matching items. 211 // Find matching items.
292 const ExtensionMenuItem::List* all_items = manager->MenuItems(extension_id); 212 const ExtensionMenuItem::List* all_items = manager->MenuItems(extension_id);
293 if (!all_items || all_items->empty()) 213 if (!all_items || all_items->empty())
294 return; 214 return;
295 bool can_cross_incognito = service->CanCrossIncognito(extension); 215 bool can_cross_incognito = service->CanCrossIncognito(extension);
296 ExtensionMenuItem::List items = 216 ExtensionMenuItem::List items =
297 GetRelevantExtensionItems(*all_items, params_, profile_, 217 ContextMenuUtils::GetRelevantExtensionItems(*all_items,
298 can_cross_incognito); 218 params_,
219 profile_,
220 can_cross_incognito);
299 if (items.empty()) 221 if (items.empty())
300 return; 222 return;
301 223
302 // If this is the first extension-provided menu item, add a separator. 224 // If this is the first extension-provided menu item, add a separator.
303 if (*index == 0) 225 if (*index == 0)
304 menu_model_.AddSeparator(); 226 menu_model_.AddSeparator();
305 227
306 int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++; 228 int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++;
307 229
308 // Extensions are only allowed one top-level slot (and it can't be a radio or 230 // Extensions are only allowed one top-level slot (and it can't be a radio or
309 // checkbox item because we are going to put the extension icon next to it). 231 // checkbox item because we are going to put the extension icon next to it).
310 // If they have more than that, we automatically push them into a submenu. 232 // If they have more than that, we automatically push them into a submenu.
311 string16 title; 233 string16 title;
312 ExtensionMenuItem::List submenu_items; 234 ExtensionMenuItem::List submenu_items;
313 if (items.size() > 1 || items[0]->type() != ExtensionMenuItem::NORMAL) { 235 if (items.size() > 1 || items[0]->type() != ExtensionMenuItem::NORMAL) {
314 title = UTF8ToUTF16(extension->name()); 236 title = UTF8ToUTF16(extension->name());
315 submenu_items = items; 237 submenu_items = items;
316 } else { 238 } else {
317 ExtensionMenuItem* item = items[0]; 239 ExtensionMenuItem* item = items[0];
318 extension_item_map_[menu_id] = item->id(); 240 extension_item_map_[menu_id] = item->id();
319 title = item->TitleWithReplacement(PrintableSelectionText(), 241 title = item->TitleWithReplacement(PrintableSelectionText(),
320 kMaxExtensionItemTitleLength); 242 kMaxExtensionItemTitleLength);
321 submenu_items = GetRelevantExtensionItems(item->children(), params_, 243 submenu_items = ContextMenuUtils::GetRelevantExtensionItems(
322 profile_, can_cross_incognito); 244 item->children(), params_, profile_, can_cross_incognito);
323 } 245 }
324 246
325 // Now add our item(s) to the menu_model_. 247 // Now add our item(s) to the menu_model_.
326 if (submenu_items.empty()) { 248 if (submenu_items.empty()) {
327 menu_model_.AddItem(menu_id, title); 249 menu_model_.AddItem(menu_id, title);
328 } else { 250 } else {
329 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(this); 251 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(this);
330 extension_menu_models_.push_back(submenu); 252 extension_menu_models_.push_back(submenu);
331 menu_model_.AddSubMenu(menu_id, title, submenu); 253 menu_model_.AddSubMenu(menu_id, title, submenu);
332 RecursivelyAppendExtensionItems(submenu_items, can_cross_incognito, submenu, 254 RecursivelyAppendExtensionItems(submenu_items, can_cross_incognito, submenu,
(...skipping 24 matching lines...) Expand all
357 } 279 }
358 280
359 int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++; 281 int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++;
360 if (menu_id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) 282 if (menu_id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST)
361 return; 283 return;
362 extension_item_map_[menu_id] = item->id(); 284 extension_item_map_[menu_id] = item->id();
363 string16 title = item->TitleWithReplacement(selection_text, 285 string16 title = item->TitleWithReplacement(selection_text,
364 kMaxExtensionItemTitleLength); 286 kMaxExtensionItemTitleLength);
365 if (item->type() == ExtensionMenuItem::NORMAL) { 287 if (item->type() == ExtensionMenuItem::NORMAL) {
366 ExtensionMenuItem::List children = 288 ExtensionMenuItem::List children =
367 GetRelevantExtensionItems(item->children(), params_, 289 ContextMenuUtils::GetRelevantExtensionItems(
368 profile_, can_cross_incognito); 290 item->children(), params_, profile_, can_cross_incognito);
369 if (children.empty()) { 291 if (children.empty()) {
370 menu_model->AddItem(menu_id, title); 292 menu_model->AddItem(menu_id, title);
371 } else { 293 } else {
372 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(this); 294 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(this);
373 extension_menu_models_.push_back(submenu); 295 extension_menu_models_.push_back(submenu);
374 menu_model->AddSubMenu(menu_id, title, submenu); 296 menu_model->AddSubMenu(menu_id, title, submenu);
375 RecursivelyAppendExtensionItems(children, can_cross_incognito, 297 RecursivelyAppendExtensionItems(children, can_cross_incognito,
376 submenu, index); 298 submenu, index);
377 } 299 }
378 } else if (item->type() == ExtensionMenuItem::CHECKBOX) { 300 } else if (item->type() == ExtensionMenuItem::CHECKBOX) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 332
411 menu_model_.SetIcon(index, icon); 333 menu_model_.SetIcon(index, icon);
412 } 334 }
413 335
414 void RenderViewContextMenu::AppendAllExtensionItems() { 336 void RenderViewContextMenu::AppendAllExtensionItems() {
415 extension_item_map_.clear(); 337 extension_item_map_.clear();
416 ExtensionService* service = profile_->GetExtensionService(); 338 ExtensionService* service = profile_->GetExtensionService();
417 if (!service) 339 if (!service)
418 return; // In unit-tests, we may not have an ExtensionService. 340 return; // In unit-tests, we may not have an ExtensionService.
419 ExtensionMenuManager* menu_manager = service->menu_manager(); 341 ExtensionMenuManager* menu_manager = service->menu_manager();
420 const GURL& document_url = GetDocumentURL(params_); 342 const GURL& document_url = ContextMenuUtils::GetDocumentURL(params_);
421 if (!menu_manager->HasAllowedScheme(document_url)) 343 if (!menu_manager->HasAllowedScheme(document_url))
422 return; 344 return;
423 345
424 // Get a list of extension id's that have context menu items, and sort it by 346 // Get a list of extension id's that have context menu items, and sort it by
425 // the extension's name. 347 // the extension's name.
426 std::set<std::string> ids = menu_manager->ExtensionIds(); 348 std::set<std::string> ids = menu_manager->ExtensionIds();
427 std::vector<std::pair<std::string, std::string> > sorted_ids; 349 std::vector<std::pair<std::string, std::string> > sorted_ids;
428 for (std::set<std::string>::iterator i = ids.begin(); i != ids.end(); ++i) { 350 for (std::set<std::string>::iterator i = ids.begin(); i != ids.end(); ++i) {
429 const Extension* extension = service->GetExtensionById(*i, false); 351 const Extension* extension = service->GetExtensionById(*i, false);
430 if (extension) 352 if (extension)
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 break; 421 break;
500 case WebContextMenuData::MediaTypeVideo: 422 case WebContextMenuData::MediaTypeVideo:
501 AppendVideoItems(); 423 AppendVideoItems();
502 break; 424 break;
503 case WebContextMenuData::MediaTypeAudio: 425 case WebContextMenuData::MediaTypeAudio:
504 AppendAudioItems(); 426 AppendAudioItems();
505 break; 427 break;
506 case WebContextMenuData::MediaTypePlugin: 428 case WebContextMenuData::MediaTypePlugin:
507 AppendPluginItems(); 429 AppendPluginItems();
508 break; 430 break;
509 #ifdef WEBCONTEXT_MEDIATYPEFILE_DEFINED
510 case WebContextMenuData::MediaTypeFile: 431 case WebContextMenuData::MediaTypeFile:
432 AppendFileItems();
511 break; 433 break;
512 #endif
513 } 434 }
514 435
515 if (params_.is_editable) 436 if (params_.is_editable)
516 AppendEditableItems(); 437 AppendEditableItems();
517 else if (has_selection) 438 else if (has_selection)
518 AppendCopyItem(); 439 AppendCopyItem();
519 440
520 if (has_selection) 441 if (has_selection)
521 AppendSearchProvider(); 442 AppendSearchProvider();
522 443
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 AppendMediaItems(); 513 AppendMediaItems();
593 menu_model_.AddSeparator(); 514 menu_model_.AddSeparator();
594 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEAVAS, 515 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEAVAS,
595 IDS_CONTENT_CONTEXT_SAVEVIDEOAS); 516 IDS_CONTENT_CONTEXT_SAVEVIDEOAS);
596 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYAVLOCATION, 517 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYAVLOCATION,
597 IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION); 518 IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION);
598 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENAVNEWTAB, 519 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENAVNEWTAB,
599 IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB); 520 IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB);
600 } 521 }
601 522
523 void RenderViewContextMenu::AppendFileItems() {
524 // TODO(zelidrag): Add file context operations here (i.e. cut, copy, paste...)
525 }
526
602 void RenderViewContextMenu::AppendMediaItems() { 527 void RenderViewContextMenu::AppendMediaItems() {
603 int media_flags = params_.media_flags; 528 int media_flags = params_.media_flags;
604 529
605 menu_model_.AddItemWithStringId( 530 menu_model_.AddItemWithStringId(
606 IDC_CONTENT_CONTEXT_PLAYPAUSE, 531 IDC_CONTENT_CONTEXT_PLAYPAUSE,
607 media_flags & WebContextMenuData::MediaPaused ? 532 media_flags & WebContextMenuData::MediaPaused ?
608 IDS_CONTENT_CONTEXT_PLAY : 533 IDS_CONTENT_CONTEXT_PLAY :
609 IDS_CONTENT_CONTEXT_PAUSE); 534 IDS_CONTENT_CONTEXT_PAUSE);
610 535
611 menu_model_.AddItemWithStringId( 536 menu_model_.AddItemWithStringId(
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), 1470 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
1546 g_browser_process->clipboard()); 1471 g_browser_process->clipboard());
1547 } 1472 }
1548 1473
1549 void RenderViewContextMenu::MediaPlayerActionAt( 1474 void RenderViewContextMenu::MediaPlayerActionAt(
1550 const gfx::Point& location, 1475 const gfx::Point& location,
1551 const WebMediaPlayerAction& action) { 1476 const WebMediaPlayerAction& action) {
1552 source_tab_contents_->render_view_host()->MediaPlayerActionAt( 1477 source_tab_contents_->render_view_host()->MediaPlayerActionAt(
1553 location, action); 1478 location, action);
1554 } 1479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698