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
3 // found in the LICENSE file.
5 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
11 #include "apps/app_load_service.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/metrics/histogram.h"
15 #include "base/prefs/pref_member.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "chrome/app/chrome_command_ids.h"
22 #include "chrome/browser/app_mode/app_mode_utils.h"
23 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
24 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
28 #include "chrome/browser/devtools/devtools_window.h"
29 #include "chrome/browser/download/download_service.h"
30 #include "chrome/browser/download/download_service_factory.h"
31 #include "chrome/browser/download/download_stats.h"
32 #include "chrome/browser/extensions/devtools_util.h"
33 #include "chrome/browser/extensions/extension_service.h"
34 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
35 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
36 #include "chrome/browser/prefs/incognito_mode_prefs.h"
37 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/profiles/profile_io_data.h"
39 #include "chrome/browser/renderer_context_menu/context_menu_content_type_factory.h"
40 #include "chrome/browser/renderer_context_menu/spellchecker_submenu_observer.h"
41 #include "chrome/browser/renderer_context_menu/spelling_menu_observer.h"
42 #include "chrome/browser/search/search.h"
43 #include "chrome/browser/search_engines/template_url_service_factory.h"
44 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
45 #include "chrome/browser/spellchecker/spellcheck_service.h"
46 #include "chrome/browser/tab_contents/retargeting_details.h"
47 #include "chrome/browser/translate/chrome_translate_client.h"
48 #include "chrome/browser/translate/translate_service.h"
49 #include "chrome/browser/ui/browser.h"
50 #include "chrome/browser/ui/browser_commands.h"
51 #include "chrome/browser/ui/browser_finder.h"
52 #include "chrome/browser/ui/chrome_pages.h"
53 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
54 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
55 #include "chrome/common/chrome_constants.h"
56 #include "chrome/common/chrome_switches.h"
57 #include "chrome/common/content_restriction.h"
58 #include "chrome/common/net/url_util.h"
59 #include "chrome/common/pref_names.h"
60 #include "chrome/common/render_messages.h"
61 #include "chrome/common/spellcheck_messages.h"
62 #include "chrome/common/url_constants.h"
63 #include "components/google/core/browser/google_util.h"
64 #include "components/metrics/proto/omnibox_input_type.pb.h"
65 #include "components/omnibox/autocomplete_match.h"
66 #include "components/search_engines/template_url.h"
67 #include "components/search_engines/template_url_service.h"
68 #include "components/translate/core/browser/translate_download_manager.h"
69 #include "components/translate/core/browser/translate_manager.h"
70 #include "components/translate/core/browser/translate_prefs.h"
71 #include "components/user_prefs/user_prefs.h"
72 #include "content/public/browser/child_process_security_policy.h"
73 #include "content/public/browser/download_manager.h"
74 #include "content/public/browser/download_save_info.h"
75 #include "content/public/browser/download_url_parameters.h"
76 #include "content/public/browser/navigation_details.h"
77 #include "content/public/browser/navigation_entry.h"
78 #include "content/public/browser/notification_service.h"
79 #include "content/public/browser/render_frame_host.h"
80 #include "content/public/browser/render_process_host.h"
81 #include "content/public/browser/render_view_host.h"
82 #include "content/public/browser/render_widget_host_view.h"
83 #include "content/public/browser/user_metrics.h"
84 #include "content/public/browser/web_contents.h"
85 #include "content/public/common/menu_item.h"
86 #include "content/public/common/ssl_status.h"
87 #include "content/public/common/url_utils.h"
88 #include "extensions/browser/extension_host.h"
89 #include "extensions/browser/extension_system.h"
90 #include "extensions/browser/view_type_utils.h"
91 #include "extensions/common/extension.h"
92 #include "grit/generated_resources.h"
93 #include "net/base/escape.h"
94 #include "third_party/WebKit/public/web/WebContextMenuData.h"
95 #include "third_party/WebKit/public/web/WebMediaPlayerAction.h"
96 #include "third_party/WebKit/public/web/WebPluginAction.h"
97 #include "ui/base/clipboard/clipboard.h"
98 #include "ui/base/l10n/l10n_util.h"
99 #include "ui/gfx/favicon_size.h"
100 #include "ui/gfx/point.h"
101 #include "ui/gfx/size.h"
102 #include "ui/gfx/text_elider.h"
104 #if defined(ENABLE_PRINTING)
105 #include "chrome/common/print_messages.h"
107 #if defined(ENABLE_FULL_PRINTING)
108 #include "chrome/browser/printing/print_preview_context_menu_observer.h"
109 #include "chrome/browser/printing/print_preview_dialog_controller.h"
110 #include "chrome/browser/printing/print_view_manager.h"
112 #include "chrome/browser/printing/print_view_manager_basic.h"
113 #endif // defined(ENABLE_FULL_PRINTING)
114 #endif // defined(ENABLE_PRINTING)
116 using base::UserMetricsAction;
117 using blink::WebContextMenuData;
118 using blink::WebMediaPlayerAction;
119 using blink::WebPluginAction;
120 using blink::WebString;
122 using content::BrowserContext;
123 using content::ChildProcessSecurityPolicy;
124 using content::DownloadManager;
125 using content::DownloadUrlParameters;
126 using content::NavigationController;
127 using content::NavigationEntry;
128 using content::OpenURLParams;
129 using content::RenderFrameHost;
130 using content::RenderViewHost;
131 using content::SSLStatus;
132 using content::WebContents;
133 using extensions::ContextMenuMatcher;
134 using extensions::Extension;
135 using extensions::MenuItem;
136 using extensions::MenuManager;
140 const int kImageSearchThumbnailMinSize = 300 * 300;
141 const int kImageSearchThumbnailMaxWidth = 600;
142 const int kImageSearchThumbnailMaxHeight = 600;
144 // Maps UMA enumeration to IDC. IDC could be changed so we can't use
145 // just them and |UMA_HISTOGRAM_CUSTOM_ENUMERATION|.
146 // Never change mapping or reuse |enum_id|. Always push back new items.
147 // Items that is not used any more by |RenderViewContextMenu.ExecuteCommand|
148 // could be deleted, but don't change the rest of |kUmaEnumToControlId|.
149 const struct UmaEnumCommandIdPair {
152 } kUmaEnumToControlId[] = {
154 enum id for 0, 1 are detected using
155 RenderViewContextMenu::IsContentCustomCommandId and
156 ContextMenuMatcher::IsExtensionsCustomCommandId
158 {2, IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST},
159 {3, IDC_CONTENT_CONTEXT_OPENLINKNEWTAB},
160 {4, IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW},
161 {5, IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD},
162 {6, IDC_CONTENT_CONTEXT_SAVELINKAS},
163 {7, IDC_CONTENT_CONTEXT_SAVEAVAS},
164 {8, IDC_CONTENT_CONTEXT_SAVEIMAGEAS},
165 {9, IDC_CONTENT_CONTEXT_COPYLINKLOCATION},
166 {10, IDC_CONTENT_CONTEXT_COPYIMAGELOCATION},
167 {11, IDC_CONTENT_CONTEXT_COPYAVLOCATION},
168 {12, IDC_CONTENT_CONTEXT_COPYIMAGE},
169 {13, IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB},
170 {14, IDC_CONTENT_CONTEXT_OPENAVNEWTAB},
171 {15, IDC_CONTENT_CONTEXT_PLAYPAUSE},
172 {16, IDC_CONTENT_CONTEXT_MUTE},
173 {17, IDC_CONTENT_CONTEXT_LOOP},
174 {18, IDC_CONTENT_CONTEXT_CONTROLS},
175 {19, IDC_CONTENT_CONTEXT_ROTATECW},
176 {20, IDC_CONTENT_CONTEXT_ROTATECCW},
181 {25, IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP},
182 {26, IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP},
184 {28, IDC_VIEW_SOURCE},
185 {29, IDC_CONTENT_CONTEXT_INSPECTELEMENT},
186 {30, IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE},
187 {31, IDC_CONTENT_CONTEXT_VIEWPAGEINFO},
188 {32, IDC_CONTENT_CONTEXT_TRANSLATE},
189 {33, IDC_CONTENT_CONTEXT_RELOADFRAME},
190 {34, IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE},
191 {35, IDC_CONTENT_CONTEXT_VIEWFRAMEINFO},
192 {36, IDC_CONTENT_CONTEXT_UNDO},
193 {37, IDC_CONTENT_CONTEXT_REDO},
194 {38, IDC_CONTENT_CONTEXT_CUT},
195 {39, IDC_CONTENT_CONTEXT_COPY},
196 {40, IDC_CONTENT_CONTEXT_PASTE},
197 {41, IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE},
198 {42, IDC_CONTENT_CONTEXT_DELETE},
199 {43, IDC_CONTENT_CONTEXT_SELECTALL},
200 {44, IDC_CONTENT_CONTEXT_SEARCHWEBFOR},
201 {45, IDC_CONTENT_CONTEXT_GOTOURL},
202 {46, IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS},
203 {47, IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_SETTINGS},
204 {48, IDC_CONTENT_CONTEXT_ADDSEARCHENGINE},
205 {52, IDC_CONTENT_CONTEXT_OPENLINKWITH},
206 {53, IDC_CHECK_SPELLING_WHILE_TYPING},
207 {54, IDC_SPELLCHECK_MENU},
208 {55, IDC_CONTENT_CONTEXT_SPELLING_TOGGLE},
209 {56, IDC_SPELLCHECK_LANGUAGES_FIRST},
210 {57, IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE},
211 {58, IDC_SPELLCHECK_SUGGESTION_0},
212 {59, IDC_SPELLCHECK_ADD_TO_DICTIONARY},
213 {60, IDC_SPELLPANEL_TOGGLE},
214 // Add new items here and use |enum_id| from the next line.
215 {61, 0}, // Must be the last. Increment |enum_id| when new IDC was added.
218 // Collapses large ranges of ids before looking for UMA enum.
219 int CollapseCommandsForUMA(int id) {
220 DCHECK(!RenderViewContextMenu::IsContentCustomCommandId(id));
221 DCHECK(!ContextMenuMatcher::IsExtensionsCustomCommandId(id));
223 if (id >= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST &&
224 id <= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_LAST) {
225 return IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST;
228 if (id >= IDC_SPELLCHECK_LANGUAGES_FIRST &&
229 id <= IDC_SPELLCHECK_LANGUAGES_LAST) {
230 return IDC_SPELLCHECK_LANGUAGES_FIRST;
233 if (id >= IDC_SPELLCHECK_SUGGESTION_0 &&
234 id <= IDC_SPELLCHECK_SUGGESTION_LAST) {
235 return IDC_SPELLCHECK_SUGGESTION_0;
241 // Returns UMA enum value for command specified by |id| or -1 if not found.
242 int FindUMAEnumValueForCommand(int id) {
243 if (RenderViewContextMenu::IsContentCustomCommandId(id))
246 if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
249 id = CollapseCommandsForUMA(id);
250 const size_t kMappingSize = arraysize(kUmaEnumToControlId);
251 for (size_t i = 0; i < kMappingSize; ++i) {
252 if (kUmaEnumToControlId[i].control_id == id) {
253 return kUmaEnumToControlId[i].enum_id;
259 // Usually a new tab is expected where this function is used,
260 // however users should be able to open a tab in background
261 // or in a new window.
262 WindowOpenDisposition ForceNewTabDispositionFromEventFlags(
264 WindowOpenDisposition disposition =
265 ui::DispositionFromEventFlags(event_flags);
266 return disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition;
269 // Helper function to escape "&" as "&&".
270 void EscapeAmpersands(base::string16* text) {
271 base::ReplaceChars(*text, base::ASCIIToUTF16("&"), base::ASCIIToUTF16("&&"),
275 // Returns the preference of the profile represented by the |context|.
276 PrefService* GetPrefs(content::BrowserContext* context) {
277 return user_prefs::UserPrefs::Get(context);
280 bool custom_id_ranges_initialized = false;
285 bool RenderViewContextMenu::IsDevToolsURL(const GURL& url) {
286 return url.SchemeIs(content::kChromeDevToolsScheme);
290 bool RenderViewContextMenu::IsInternalResourcesURL(const GURL& url) {
291 if (!url.SchemeIs(content::kChromeUIScheme))
293 return url.host() == chrome::kChromeUISyncResourcesHost;
296 static const int kSpellcheckRadioGroup = 1;
298 RenderViewContextMenu::RenderViewContextMenu(
299 content::RenderFrameHost* render_frame_host,
300 const content::ContextMenuParams& params)
301 : RenderViewContextMenuBase(render_frame_host, params),
302 extension_items_(browser_context_,
305 base::Bind(MenuItemMatchesParams, params_)),
306 protocol_handler_submenu_model_(this),
307 protocol_handler_registry_(
308 ProtocolHandlerRegistryFactory::GetForBrowserContext(GetProfile())) {
309 if (!custom_id_ranges_initialized) {
310 custom_id_ranges_initialized = true;
311 SetContentCustomCommandIdRange(IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
312 IDC_CONTENT_CONTEXT_CUSTOM_LAST);
314 set_content_type(ContextMenuContentTypeFactory::Create(
315 source_web_contents_, params));
318 RenderViewContextMenu::~RenderViewContextMenu() {
321 // Menu construction functions -------------------------------------------------
323 static bool ExtensionPatternMatch(const extensions::URLPatternSet& patterns,
325 // No patterns means no restriction, so that implicitly matches.
326 if (patterns.is_empty())
328 return patterns.MatchesURL(url);
332 bool RenderViewContextMenu::ExtensionContextAndPatternMatch(
333 const content::ContextMenuParams& params,
334 MenuItem::ContextList contexts,
335 const extensions::URLPatternSet& target_url_patterns) {
336 const bool has_link = !params.link_url.is_empty();
337 const bool has_selection = !params.selection_text.empty();
338 const bool in_frame = !params.frame_url.is_empty();
340 if (contexts.Contains(MenuItem::ALL) ||
341 (has_selection && contexts.Contains(MenuItem::SELECTION)) ||
342 (params.is_editable && contexts.Contains(MenuItem::EDITABLE)) ||
343 (in_frame && contexts.Contains(MenuItem::FRAME)))
346 if (has_link && contexts.Contains(MenuItem::LINK) &&
347 ExtensionPatternMatch(target_url_patterns, params.link_url))
350 switch (params.media_type) {
351 case WebContextMenuData::MediaTypeImage:
352 if (contexts.Contains(MenuItem::IMAGE) &&
353 ExtensionPatternMatch(target_url_patterns, params.src_url))
357 case WebContextMenuData::MediaTypeVideo:
358 if (contexts.Contains(MenuItem::VIDEO) &&
359 ExtensionPatternMatch(target_url_patterns, params.src_url))
363 case WebContextMenuData::MediaTypeAudio:
364 if (contexts.Contains(MenuItem::AUDIO) &&
365 ExtensionPatternMatch(target_url_patterns, params.src_url))
373 // PAGE is the least specific context, so we only examine that if none of the
374 // other contexts apply (except for FRAME, which is included in PAGE for
375 // backwards compatibility).
376 if (!has_link && !has_selection && !params.is_editable &&
377 params.media_type == WebContextMenuData::MediaTypeNone &&
378 contexts.Contains(MenuItem::PAGE))
384 static const GURL& GetDocumentURL(const content::ContextMenuParams& params) {
385 return params.frame_url.is_empty() ? params.page_url : params.frame_url;
389 bool RenderViewContextMenu::MenuItemMatchesParams(
390 const content::ContextMenuParams& params,
391 const extensions::MenuItem* item) {
392 bool match = ExtensionContextAndPatternMatch(params, item->contexts(),
393 item->target_url_patterns());
397 const GURL& document_url = GetDocumentURL(params);
398 return ExtensionPatternMatch(item->document_url_patterns(), document_url);
401 void RenderViewContextMenu::AppendAllExtensionItems() {
402 extension_items_.Clear();
403 ExtensionService* service =
404 extensions::ExtensionSystem::Get(browser_context_)->extension_service();
406 return; // In unit-tests, we may not have an ExtensionService.
408 MenuManager* menu_manager = MenuManager::Get(browser_context_);
412 base::string16 printable_selection_text = PrintableSelectionText();
413 EscapeAmpersands(&printable_selection_text);
415 // Get a list of extension id's that have context menu items, and sort by the
416 // top level context menu title of the extension.
417 std::set<MenuItem::ExtensionKey> ids = menu_manager->ExtensionIds();
418 std::vector<base::string16> sorted_menu_titles;
419 std::map<base::string16, std::string> map_ids;
420 for (std::set<MenuItem::ExtensionKey>::iterator iter = ids.begin();
423 const Extension* extension =
424 service->GetExtensionById(iter->extension_id, false);
425 // Platform apps have their context menus created directly in
426 // AppendPlatformAppItems.
427 if (extension && !extension->is_platform_app()) {
428 base::string16 menu_title = extension_items_.GetTopLevelContextMenuTitle(
429 *iter, printable_selection_text);
430 map_ids[menu_title] = iter->extension_id;
431 sorted_menu_titles.push_back(menu_title);
434 if (sorted_menu_titles.empty())
437 const std::string app_locale = g_browser_process->GetApplicationLocale();
438 l10n_util::SortStrings16(app_locale, &sorted_menu_titles);
441 for (size_t i = 0; i < sorted_menu_titles.size(); ++i) {
442 const std::string& id = map_ids[sorted_menu_titles[i]];
443 const MenuItem::ExtensionKey extension_key(id);
444 extension_items_.AppendExtensionItems(extension_key,
445 printable_selection_text,
447 false); // is_action_menu
451 void RenderViewContextMenu::AppendCurrentExtensionItems() {
452 // Avoid appending extension related items when |extension| is null.
453 // For Panel, this happens when the panel is navigated to a url outside of the
454 // extension's package.
455 const Extension* extension = GetExtension();
457 // Only add extension items from this extension.
459 const MenuItem::ExtensionKey key(
461 extensions::WebViewGuest::GetViewInstanceId(source_web_contents_));
462 extension_items_.AppendExtensionItems(key,
463 PrintableSelectionText(),
465 false); // is_action_menu
469 void RenderViewContextMenu::InitMenu() {
470 RenderViewContextMenuBase::InitMenu();
472 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PAGE))
475 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_FRAME)) {
476 // Merge in frame items with page items if we clicked within a frame that
478 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
482 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_LINK)) {
484 if (params_.media_type != WebContextMenuData::MediaTypeNone)
485 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
488 if (content_type_->SupportsGroup(
489 ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE)) {
493 if (content_type_->SupportsGroup(
494 ContextMenuContentType::ITEM_GROUP_SEARCHWEBFORIMAGE)) {
495 AppendSearchWebForImageItems();
498 if (content_type_->SupportsGroup(
499 ContextMenuContentType::ITEM_GROUP_MEDIA_VIDEO)) {
503 if (content_type_->SupportsGroup(
504 ContextMenuContentType::ITEM_GROUP_MEDIA_AUDIO)) {
508 if (content_type_->SupportsGroup(
509 ContextMenuContentType::ITEM_GROUP_MEDIA_CANVAS)) {
513 if (content_type_->SupportsGroup(
514 ContextMenuContentType::ITEM_GROUP_MEDIA_PLUGIN)) {
518 // ITEM_GROUP_MEDIA_FILE has no specific items.
520 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_EDITABLE))
521 AppendEditableItems();
523 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_COPY)) {
524 DCHECK(!content_type_->SupportsGroup(
525 ContextMenuContentType::ITEM_GROUP_EDITABLE));
529 if (content_type_->SupportsGroup(
530 ContextMenuContentType::ITEM_GROUP_SEARCH_PROVIDER)) {
531 AppendSearchProvider();
534 if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PRINT))
537 if (content_type_->SupportsGroup(
538 ContextMenuContentType::ITEM_GROUP_ALL_EXTENSION)) {
539 DCHECK(!content_type_->SupportsGroup(
540 ContextMenuContentType::ITEM_GROUP_CURRENT_EXTENSION));
541 AppendAllExtensionItems();
544 if (content_type_->SupportsGroup(
545 ContextMenuContentType::ITEM_GROUP_CURRENT_EXTENSION)) {
546 DCHECK(!content_type_->SupportsGroup(
547 ContextMenuContentType::ITEM_GROUP_ALL_EXTENSION));
548 AppendCurrentExtensionItems();
551 if (content_type_->SupportsGroup(
552 ContextMenuContentType::ITEM_GROUP_DEVELOPER)) {
553 AppendDeveloperItems();
556 if (content_type_->SupportsGroup(
557 ContextMenuContentType::ITEM_GROUP_DEVTOOLS_UNPACKED_EXT)) {
558 AppendDevtoolsForUnpackedExtensions();
561 if (content_type_->SupportsGroup(
562 ContextMenuContentType::ITEM_GROUP_PRINT_PREVIEW)) {
563 AppendPrintPreviewItems();
567 Profile* RenderViewContextMenu::GetProfile() {
568 return Profile::FromBrowserContext(browser_context_);
571 void RenderViewContextMenu::RecordUsedItem(int id) {
572 int enum_id = FindUMAEnumValueForCommand(id);
574 const size_t kMappingSize = arraysize(kUmaEnumToControlId);
575 UMA_HISTOGRAM_ENUMERATION("RenderViewContextMenu.Used", enum_id,
576 kUmaEnumToControlId[kMappingSize - 1].enum_id);
578 NOTREACHED() << "Update kUmaEnumToControlId. Unhanded IDC: " << id;
582 void RenderViewContextMenu::RecordShownItem(int id) {
583 int enum_id = FindUMAEnumValueForCommand(id);
585 const size_t kMappingSize = arraysize(kUmaEnumToControlId);
586 UMA_HISTOGRAM_ENUMERATION("RenderViewContextMenu.Shown", enum_id,
587 kUmaEnumToControlId[kMappingSize - 1].enum_id);
589 // Just warning here. It's harder to maintain list of all possibly
590 // visible items than executable items.
591 DLOG(ERROR) << "Update kUmaEnumToControlId. Unhanded IDC: " << id;
595 #if defined(ENABLE_PLUGINS)
596 void RenderViewContextMenu::HandleAuthorizeAllPlugins() {
597 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
598 source_web_contents_, false, std::string());
602 void RenderViewContextMenu::AppendPrintPreviewItems() {
603 #if defined(ENABLE_FULL_PRINTING)
604 if (!print_preview_menu_observer_.get()) {
605 print_preview_menu_observer_.reset(
606 new PrintPreviewContextMenuObserver(source_web_contents_));
609 observers_.AddObserver(print_preview_menu_observer_.get());
613 const Extension* RenderViewContextMenu::GetExtension() const {
614 extensions::ExtensionSystem* system =
615 extensions::ExtensionSystem::Get(browser_context_);
616 // There is no process manager in some tests.
617 if (!system->process_manager())
620 return system->process_manager()->GetExtensionForRenderViewHost(
621 source_web_contents_->GetRenderViewHost());
624 void RenderViewContextMenu::AppendDeveloperItems() {
625 // Show Inspect Element in DevTools itself only in case of the debug
627 bool show_developer_items = !IsDevToolsURL(params_.page_url);
629 #if defined(DEBUG_DEVTOOLS)
630 show_developer_items = true;
633 if (!show_developer_items)
636 // In the DevTools popup menu, "developer items" is normally the only
637 // section, so omit the separator there.
638 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
639 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_INSPECTELEMENT,
640 IDS_CONTENT_CONTEXT_INSPECTELEMENT);
643 void RenderViewContextMenu::AppendDevtoolsForUnpackedExtensions() {
644 // Add a separator if there are any items already in the menu.
645 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
647 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP,
648 IDS_CONTENT_CONTEXT_RELOAD_PACKAGED_APP);
649 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP,
650 IDS_CONTENT_CONTEXT_RESTART_APP);
651 AppendDeveloperItems();
652 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE,
653 IDS_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE);
656 void RenderViewContextMenu::AppendLinkItems() {
657 if (!params_.link_url.is_empty()) {
658 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB,
659 IDS_CONTENT_CONTEXT_OPENLINKNEWTAB);
660 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW,
661 IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW);
662 if (params_.link_url.is_valid()) {
663 AppendProtocolHandlerSubMenu();
666 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD,
667 IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD);
668 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVELINKAS,
669 IDS_CONTENT_CONTEXT_SAVELINKAS);
672 menu_model_.AddItemWithStringId(
673 IDC_CONTENT_CONTEXT_COPYLINKLOCATION,
674 params_.link_url.SchemeIs(url::kMailToScheme) ?
675 IDS_CONTENT_CONTEXT_COPYEMAILADDRESS :
676 IDS_CONTENT_CONTEXT_COPYLINKLOCATION);
679 void RenderViewContextMenu::AppendImageItems() {
680 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEIMAGEAS,
681 IDS_CONTENT_CONTEXT_SAVEIMAGEAS);
682 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYIMAGELOCATION,
683 IDS_CONTENT_CONTEXT_COPYIMAGELOCATION);
684 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYIMAGE,
685 IDS_CONTENT_CONTEXT_COPYIMAGE);
686 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB,
687 IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB);
690 void RenderViewContextMenu::AppendSearchWebForImageItems() {
691 TemplateURLService* service =
692 TemplateURLServiceFactory::GetForProfile(GetProfile());
693 const TemplateURL* const default_provider =
694 service->GetDefaultSearchProvider();
695 if (params_.has_image_contents && default_provider &&
696 !default_provider->image_url().empty() &&
697 default_provider->image_url_ref().IsValid(service->search_terms_data())) {
699 IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE,
700 l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_SEARCHWEBFORIMAGE,
701 default_provider->short_name()));
705 void RenderViewContextMenu::AppendAudioItems() {
707 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
708 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEAVAS,
709 IDS_CONTENT_CONTEXT_SAVEAUDIOAS);
710 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYAVLOCATION,
711 IDS_CONTENT_CONTEXT_COPYAUDIOLOCATION);
712 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENAVNEWTAB,
713 IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB);
716 void RenderViewContextMenu::AppendCanvasItems() {
717 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEIMAGEAS,
718 IDS_CONTENT_CONTEXT_SAVEIMAGEAS);
719 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYIMAGE,
720 IDS_CONTENT_CONTEXT_COPYIMAGE);
723 void RenderViewContextMenu::AppendVideoItems() {
725 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
726 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEAVAS,
727 IDS_CONTENT_CONTEXT_SAVEVIDEOAS);
728 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYAVLOCATION,
729 IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION);
730 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENAVNEWTAB,
731 IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB);
734 void RenderViewContextMenu::AppendMediaItems() {
735 int media_flags = params_.media_flags;
737 menu_model_.AddItemWithStringId(
738 IDC_CONTENT_CONTEXT_PLAYPAUSE,
739 media_flags & WebContextMenuData::MediaPaused ?
740 IDS_CONTENT_CONTEXT_PLAY :
741 IDS_CONTENT_CONTEXT_PAUSE);
743 menu_model_.AddItemWithStringId(
744 IDC_CONTENT_CONTEXT_MUTE,
745 media_flags & WebContextMenuData::MediaMuted ?
746 IDS_CONTENT_CONTEXT_UNMUTE :
747 IDS_CONTENT_CONTEXT_MUTE);
749 menu_model_.AddCheckItemWithStringId(IDC_CONTENT_CONTEXT_LOOP,
750 IDS_CONTENT_CONTEXT_LOOP);
751 menu_model_.AddCheckItemWithStringId(IDC_CONTENT_CONTEXT_CONTROLS,
752 IDS_CONTENT_CONTEXT_CONTROLS);
755 void RenderViewContextMenu::AppendPluginItems() {
756 if (params_.page_url == params_.src_url) {
757 // Full page plugin, so show page menu items.
758 if (params_.link_url.is_empty() && params_.selection_text.empty())
761 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEAVAS,
762 IDS_CONTENT_CONTEXT_SAVEPAGEAS);
763 menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT);
766 if (params_.media_flags & WebContextMenuData::MediaCanRotate) {
767 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
768 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_ROTATECW,
769 IDS_CONTENT_CONTEXT_ROTATECW);
770 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_ROTATECCW,
771 IDS_CONTENT_CONTEXT_ROTATECCW);
775 void RenderViewContextMenu::AppendPageItems() {
776 menu_model_.AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
777 menu_model_.AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
778 menu_model_.AddItemWithStringId(IDC_RELOAD, IDS_CONTENT_CONTEXT_RELOAD);
779 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
780 menu_model_.AddItemWithStringId(IDC_SAVE_PAGE,
781 IDS_CONTENT_CONTEXT_SAVEPAGEAS);
782 menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT);
784 if (TranslateService::IsTranslatableURL(params_.page_url)) {
785 std::string locale = g_browser_process->GetApplicationLocale();
786 locale = translate::TranslateDownloadManager::GetLanguageCode(locale);
787 base::string16 language =
788 l10n_util::GetDisplayNameForLocale(locale, locale, true);
790 IDC_CONTENT_CONTEXT_TRANSLATE,
791 l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_TRANSLATE, language));
794 menu_model_.AddItemWithStringId(IDC_VIEW_SOURCE,
795 IDS_CONTENT_CONTEXT_VIEWPAGESOURCE);
796 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_VIEWPAGEINFO,
797 IDS_CONTENT_CONTEXT_VIEWPAGEINFO);
800 void RenderViewContextMenu::AppendFrameItems() {
801 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_RELOADFRAME,
802 IDS_CONTENT_CONTEXT_RELOADFRAME);
803 // These two menu items have yet to be implemented.
804 // http://code.google.com/p/chromium/issues/detail?id=11827
805 // IDS_CONTENT_CONTEXT_SAVEFRAMEAS
806 // IDS_CONTENT_CONTEXT_PRINTFRAME
807 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE,
808 IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE);
809 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_VIEWFRAMEINFO,
810 IDS_CONTENT_CONTEXT_VIEWFRAMEINFO);
813 void RenderViewContextMenu::AppendCopyItem() {
814 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPY,
815 IDS_CONTENT_CONTEXT_COPY);
818 void RenderViewContextMenu::AppendPrintItem() {
819 if (GetPrefs(browser_context_)->GetBoolean(prefs::kPrintingEnabled) &&
820 (params_.media_type == WebContextMenuData::MediaTypeNone ||
821 params_.media_flags & WebContextMenuData::MediaCanPrint)) {
822 menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT);
826 void RenderViewContextMenu::AppendSearchProvider() {
827 DCHECK(browser_context_);
829 base::TrimWhitespace(params_.selection_text, base::TRIM_ALL,
830 ¶ms_.selection_text);
831 if (params_.selection_text.empty())
834 base::ReplaceChars(params_.selection_text, AutocompleteMatch::kInvalidChars,
835 base::ASCIIToUTF16(" "), ¶ms_.selection_text);
837 AutocompleteMatch match;
838 AutocompleteClassifierFactory::GetForProfile(GetProfile())
839 ->Classify(params_.selection_text,
842 metrics::OmniboxEventProto::INVALID_SPEC,
845 selection_navigation_url_ = match.destination_url;
846 if (!selection_navigation_url_.is_valid())
849 base::string16 printable_selection_text = PrintableSelectionText();
850 EscapeAmpersands(&printable_selection_text);
852 if (AutocompleteMatch::IsSearchType(match.type)) {
853 const TemplateURL* const default_provider =
854 TemplateURLServiceFactory::GetForProfile(GetProfile())
855 ->GetDefaultSearchProvider();
856 if (!default_provider)
859 IDC_CONTENT_CONTEXT_SEARCHWEBFOR,
860 l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_SEARCHWEBFOR,
861 default_provider->short_name(),
862 printable_selection_text));
864 if ((selection_navigation_url_ != params_.link_url) &&
865 ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
866 selection_navigation_url_.scheme())) {
868 IDC_CONTENT_CONTEXT_GOTOURL,
869 l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_GOTOURL,
870 printable_selection_text));
875 void RenderViewContextMenu::AppendEditableItems() {
876 const bool use_spellcheck_and_search = !chrome::IsRunningInForcedAppMode();
878 if (use_spellcheck_and_search)
879 AppendSpellingSuggestionsSubMenu();
881 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_UNDO,
882 IDS_CONTENT_CONTEXT_UNDO);
883 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_REDO,
884 IDS_CONTENT_CONTEXT_REDO);
885 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
886 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_CUT,
887 IDS_CONTENT_CONTEXT_CUT);
888 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPY,
889 IDS_CONTENT_CONTEXT_COPY);
890 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_PASTE,
891 IDS_CONTENT_CONTEXT_PASTE);
892 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE,
893 IDS_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE);
894 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_DELETE,
895 IDS_CONTENT_CONTEXT_DELETE);
896 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
898 if (use_spellcheck_and_search && !params_.keyword_url.is_empty()) {
899 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_ADDSEARCHENGINE,
900 IDS_CONTENT_CONTEXT_ADDSEARCHENGINE);
901 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
904 if (use_spellcheck_and_search)
905 AppendSpellcheckOptionsSubMenu();
906 AppendPlatformEditableItems();
908 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
909 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SELECTALL,
910 IDS_CONTENT_CONTEXT_SELECTALL);
913 void RenderViewContextMenu::AppendSpellingSuggestionsSubMenu() {
914 if (!spelling_menu_observer_.get())
915 spelling_menu_observer_.reset(new SpellingMenuObserver(this));
916 observers_.AddObserver(spelling_menu_observer_.get());
917 spelling_menu_observer_->InitMenu(params_);
920 void RenderViewContextMenu::AppendSpellcheckOptionsSubMenu() {
921 if (!spellchecker_submenu_observer_.get()) {
922 spellchecker_submenu_observer_.reset(new SpellCheckerSubMenuObserver(
923 this, this, kSpellcheckRadioGroup));
925 spellchecker_submenu_observer_->InitMenu(params_);
926 observers_.AddObserver(spellchecker_submenu_observer_.get());
929 void RenderViewContextMenu::AppendProtocolHandlerSubMenu() {
930 const ProtocolHandlerRegistry::ProtocolHandlerList handlers =
931 GetHandlersForLinkUrl();
932 if (handlers.empty())
934 size_t max = IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_LAST -
935 IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST;
936 for (size_t i = 0; i < handlers.size() && i <= max; i++) {
937 protocol_handler_submenu_model_.AddItem(
938 IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST + i,
939 base::UTF8ToUTF16(handlers[i].url().host()));
941 protocol_handler_submenu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
942 protocol_handler_submenu_model_.AddItem(
943 IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_SETTINGS,
944 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_OPENLINKWITH_CONFIGURE));
946 menu_model_.AddSubMenu(
947 IDC_CONTENT_CONTEXT_OPENLINKWITH,
948 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_OPENLINKWITH),
949 &protocol_handler_submenu_model_);
952 // Menu delegate functions -----------------------------------------------------
954 bool RenderViewContextMenu::IsCommandIdEnabled(int id) const {
956 bool enabled = false;
957 if (RenderViewContextMenuBase::IsCommandIdKnown(id, &enabled))
961 CoreTabHelper* core_tab_helper =
962 CoreTabHelper::FromWebContents(source_web_contents_);
963 int content_restrictions = 0;
965 content_restrictions = core_tab_helper->content_restrictions();
966 if (id == IDC_PRINT && (content_restrictions & CONTENT_RESTRICTION_PRINT))
969 if (id == IDC_SAVE_PAGE &&
970 (content_restrictions & CONTENT_RESTRICTION_SAVE)) {
974 PrefService* prefs = GetPrefs(browser_context_);
976 // Allow Spell Check language items on sub menu for text area context menu.
977 if ((id >= IDC_SPELLCHECK_LANGUAGES_FIRST) &&
978 (id < IDC_SPELLCHECK_LANGUAGES_LAST)) {
979 return prefs->GetBoolean(prefs::kEnableContinuousSpellcheck);
983 if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
984 return extension_items_.IsCommandIdEnabled(id);
986 if (id >= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST &&
987 id <= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_LAST) {
991 IncognitoModePrefs::Availability incognito_avail =
992 IncognitoModePrefs::GetAvailability(prefs);
995 return source_web_contents_->GetController().CanGoBack();
998 return source_web_contents_->GetController().CanGoForward();
1001 CoreTabHelper* core_tab_helper =
1002 CoreTabHelper::FromWebContents(source_web_contents_);
1003 if (!core_tab_helper)
1006 CoreTabHelperDelegate* core_delegate = core_tab_helper->delegate();
1007 return !core_delegate ||
1008 core_delegate->CanReloadContents(source_web_contents_);
1011 case IDC_VIEW_SOURCE:
1012 case IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE:
1013 return source_web_contents_->GetController().CanViewSource();
1015 case IDC_CONTENT_CONTEXT_INSPECTELEMENT:
1016 case IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE:
1017 case IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP:
1018 case IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP:
1019 return IsDevCommandEnabled(id);
1021 case IDC_CONTENT_CONTEXT_VIEWPAGEINFO:
1022 if (source_web_contents_->GetController().GetVisibleEntry() == NULL)
1024 // Disabled if no browser is associated (e.g. desktop notifications).
1025 if (chrome::FindBrowserWithWebContents(source_web_contents_) == NULL)
1029 case IDC_CONTENT_CONTEXT_TRANSLATE: {
1030 ChromeTranslateClient* chrome_translate_client =
1031 ChromeTranslateClient::FromWebContents(source_web_contents_);
1032 if (!chrome_translate_client)
1034 std::string original_lang =
1035 chrome_translate_client->GetLanguageState().original_language();
1036 std::string target_lang = g_browser_process->GetApplicationLocale();
1038 translate::TranslateDownloadManager::GetLanguageCode(target_lang);
1039 // Note that we intentionally enable the menu even if the original and
1040 // target languages are identical. This is to give a way to user to
1041 // translate a page that might contains text fragments in a different
1043 return ((params_.edit_flags & WebContextMenuData::CanTranslate) != 0) &&
1044 !original_lang.empty() && // Did we receive the page language yet?
1045 !chrome_translate_client->GetLanguageState().IsPageTranslated() &&
1046 !source_web_contents_->GetInterstitialPage() &&
1047 // There are some application locales which can't be used as a
1048 // target language for translation.
1049 translate::TranslateDownloadManager::IsSupportedLanguage(
1051 // Disable on the Instant Extended NTP.
1052 !chrome::IsInstantNTP(source_web_contents_);
1055 case IDC_CONTENT_CONTEXT_OPENLINKNEWTAB:
1056 case IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW:
1057 return params_.link_url.is_valid();
1059 case IDC_CONTENT_CONTEXT_COPYLINKLOCATION:
1060 return params_.unfiltered_link_url.is_valid();
1062 case IDC_CONTENT_CONTEXT_SAVELINKAS: {
1063 PrefService* local_state = g_browser_process->local_state();
1064 DCHECK(local_state);
1065 // Test if file-selection dialogs are forbidden by policy.
1066 if (!local_state->GetBoolean(prefs::kAllowFileSelectionDialogs))
1069 return params_.link_url.is_valid() &&
1070 ProfileIOData::IsHandledProtocol(params_.link_url.scheme());
1073 case IDC_CONTENT_CONTEXT_SAVEIMAGEAS: {
1074 PrefService* local_state = g_browser_process->local_state();
1075 DCHECK(local_state);
1076 // Test if file-selection dialogs are forbidden by policy.
1077 if (!local_state->GetBoolean(prefs::kAllowFileSelectionDialogs))
1080 if (params_.media_type == WebContextMenuData::MediaTypeCanvas)
1083 return params_.src_url.is_valid() &&
1084 ProfileIOData::IsHandledProtocol(params_.src_url.scheme());
1087 // The images shown in the most visited thumbnails can't be opened or
1088 // searched for conventionally.
1089 case IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB:
1090 case IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE:
1091 return params_.src_url.is_valid() &&
1092 (params_.src_url.scheme() != content::kChromeUIScheme);
1094 case IDC_CONTENT_CONTEXT_COPYIMAGE:
1095 return params_.has_image_contents;
1097 // Media control commands should all be disabled if the player is in an
1099 case IDC_CONTENT_CONTEXT_PLAYPAUSE:
1100 case IDC_CONTENT_CONTEXT_LOOP:
1101 return (params_.media_flags &
1102 WebContextMenuData::MediaInError) == 0;
1104 // Mute and unmute should also be disabled if the player has no audio.
1105 case IDC_CONTENT_CONTEXT_MUTE:
1106 return (params_.media_flags &
1107 WebContextMenuData::MediaHasAudio) != 0 &&
1108 (params_.media_flags &
1109 WebContextMenuData::MediaInError) == 0;
1111 case IDC_CONTENT_CONTEXT_CONTROLS:
1112 return (params_.media_flags &
1113 WebContextMenuData::MediaCanToggleControls) != 0;
1115 case IDC_CONTENT_CONTEXT_ROTATECW:
1116 case IDC_CONTENT_CONTEXT_ROTATECCW:
1118 (params_.media_flags & WebContextMenuData::MediaCanRotate) != 0;
1120 case IDC_CONTENT_CONTEXT_COPYAVLOCATION:
1121 case IDC_CONTENT_CONTEXT_COPYIMAGELOCATION:
1122 return params_.src_url.is_valid();
1124 case IDC_CONTENT_CONTEXT_SAVEAVAS: {
1125 PrefService* local_state = g_browser_process->local_state();
1126 DCHECK(local_state);
1127 // Test if file-selection dialogs are forbidden by policy.
1128 if (!local_state->GetBoolean(prefs::kAllowFileSelectionDialogs))
1131 const GURL& url = params_.src_url;
1133 (params_.media_flags & WebContextMenuData::MediaCanSave) &&
1134 url.is_valid() && ProfileIOData::IsHandledProtocol(url.scheme());
1135 #if defined(ENABLE_FULL_PRINTING)
1136 // Do not save the preview PDF on the print preview page.
1137 can_save = can_save &&
1138 !(printing::PrintPreviewDialogController::IsPrintPreviewURL(url));
1143 case IDC_CONTENT_CONTEXT_OPENAVNEWTAB:
1146 case IDC_SAVE_PAGE: {
1147 CoreTabHelper* core_tab_helper =
1148 CoreTabHelper::FromWebContents(source_web_contents_);
1149 if (!core_tab_helper)
1152 CoreTabHelperDelegate* core_delegate = core_tab_helper->delegate();
1153 if (core_delegate &&
1154 !core_delegate->CanSaveContents(source_web_contents_))
1157 PrefService* local_state = g_browser_process->local_state();
1158 DCHECK(local_state);
1159 // Test if file-selection dialogs are forbidden by policy.
1160 if (!local_state->GetBoolean(prefs::kAllowFileSelectionDialogs))
1163 // We save the last committed entry (which the user is looking at), as
1164 // opposed to any pending URL that hasn't committed yet.
1165 NavigationEntry* entry =
1166 source_web_contents_->GetController().GetLastCommittedEntry();
1167 return content::IsSavableURL(entry ? entry->GetURL() : GURL());
1170 case IDC_CONTENT_CONTEXT_RELOADFRAME:
1171 return params_.frame_url.is_valid();
1173 case IDC_CONTENT_CONTEXT_UNDO:
1174 return !!(params_.edit_flags & WebContextMenuData::CanUndo);
1176 case IDC_CONTENT_CONTEXT_REDO:
1177 return !!(params_.edit_flags & WebContextMenuData::CanRedo);
1179 case IDC_CONTENT_CONTEXT_CUT:
1180 return !!(params_.edit_flags & WebContextMenuData::CanCut);
1182 case IDC_CONTENT_CONTEXT_COPY:
1183 return !!(params_.edit_flags & WebContextMenuData::CanCopy);
1185 case IDC_CONTENT_CONTEXT_PASTE:
1186 case IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE: {
1187 std::vector<base::string16> types;
1189 ui::Clipboard::GetForCurrentThread()->ReadAvailableTypes(
1190 ui::CLIPBOARD_TYPE_COPY_PASTE, &types, &ignore);
1191 return !types.empty();
1193 case IDC_CONTENT_CONTEXT_DELETE:
1194 return !!(params_.edit_flags & WebContextMenuData::CanDelete);
1196 case IDC_CONTENT_CONTEXT_SELECTALL:
1197 return !!(params_.edit_flags & WebContextMenuData::CanSelectAll);
1199 case IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD:
1200 return !browser_context_->IsOffTheRecord() &&
1201 params_.link_url.is_valid() &&
1202 incognito_avail != IncognitoModePrefs::DISABLED;
1205 return prefs->GetBoolean(prefs::kPrintingEnabled) &&
1206 (params_.media_type == WebContextMenuData::MediaTypeNone ||
1207 params_.media_flags & WebContextMenuData::MediaCanPrint);
1209 case IDC_CONTENT_CONTEXT_SEARCHWEBFOR:
1210 case IDC_CONTENT_CONTEXT_GOTOURL:
1211 case IDC_SPELLPANEL_TOGGLE:
1212 case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS:
1214 case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO:
1215 // Disabled if no browser is associated (e.g. desktop notifications).
1216 if (chrome::FindBrowserWithWebContents(source_web_contents_) == NULL)
1220 case IDC_CHECK_SPELLING_WHILE_TYPING:
1221 return prefs->GetBoolean(prefs::kEnableContinuousSpellcheck);
1223 #if !defined(OS_MACOSX) && defined(OS_POSIX)
1224 // TODO(suzhe): this should not be enabled for password fields.
1225 case IDC_INPUT_METHODS_MENU:
1229 case IDC_CONTENT_CONTEXT_ADDSEARCHENGINE:
1230 return !params_.keyword_url.is_empty();
1232 case IDC_SPELLCHECK_MENU:
1235 case IDC_CONTENT_CONTEXT_OPENLINKWITH:
1238 case IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_SETTINGS:
1247 bool RenderViewContextMenu::IsCommandIdChecked(int id) const {
1248 if (RenderViewContextMenuBase::IsCommandIdChecked(id))
1251 // See if the video is set to looping.
1252 if (id == IDC_CONTENT_CONTEXT_LOOP) {
1253 return (params_.media_flags &
1254 WebContextMenuData::MediaLoop) != 0;
1257 if (id == IDC_CONTENT_CONTEXT_CONTROLS) {
1258 return (params_.media_flags &
1259 WebContextMenuData::MediaControls) != 0;
1263 if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
1264 return extension_items_.IsCommandIdChecked(id);
1269 void RenderViewContextMenu::ExecuteCommand(int id, int event_flags) {
1270 RenderViewContextMenuBase::ExecuteCommand(id, event_flags);
1271 if (command_executed_)
1273 command_executed_ = true;
1275 RenderFrameHost* render_frame_host = GetRenderFrameHost();
1277 // Process extension menu items.
1278 if (ContextMenuMatcher::IsExtensionsCustomCommandId(id)) {
1279 extension_items_.ExecuteCommand(id, source_web_contents_, params_);
1283 if (id >= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST &&
1284 id <= IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_LAST) {
1285 ProtocolHandlerRegistry::ProtocolHandlerList handlers =
1286 GetHandlersForLinkUrl();
1287 if (handlers.empty()) {
1290 content::RecordAction(
1291 UserMetricsAction("RegisterProtocolHandler.ContextMenu_Open"));
1292 int handlerIndex = id - IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST;
1293 WindowOpenDisposition disposition =
1294 ForceNewTabDispositionFromEventFlags(event_flags);
1296 handlers[handlerIndex].TranslateUrl(params_.link_url),
1297 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url,
1298 disposition, content::PAGE_TRANSITION_LINK);
1303 case IDC_CONTENT_CONTEXT_OPENLINKNEWTAB: {
1305 chrome::FindBrowserWithWebContents(source_web_contents_);
1308 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url,
1309 !browser || browser->is_app() ?
1310 NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB,
1311 content::PAGE_TRANSITION_LINK);
1314 case IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW:
1317 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url,
1318 NEW_WINDOW, content::PAGE_TRANSITION_LINK);
1321 case IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD:
1322 OpenURL(params_.link_url, GURL(), OFF_THE_RECORD,
1323 content::PAGE_TRANSITION_LINK);
1326 case IDC_CONTENT_CONTEXT_SAVELINKAS: {
1327 RecordDownloadSource(DOWNLOAD_INITIATED_BY_CONTEXT_MENU);
1328 const GURL& url = params_.link_url;
1329 const GURL& referring_url =
1330 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url;
1331 content::Referrer referrer = content::Referrer::SanitizeForRequest(
1333 content::Referrer(referring_url.GetAsReferrer(),
1334 params_.referrer_policy));
1335 DownloadManager* dlm =
1336 BrowserContext::GetDownloadManager(browser_context_);
1337 scoped_ptr<DownloadUrlParameters> dl_params(
1338 DownloadUrlParameters::FromWebContents(source_web_contents_, url));
1339 dl_params->set_referrer(referrer);
1340 dl_params->set_referrer_encoding(params_.frame_charset);
1341 dl_params->set_suggested_name(params_.suggested_filename);
1342 dl_params->set_prompt(true);
1343 dlm->DownloadUrl(dl_params.Pass());
1347 case IDC_CONTENT_CONTEXT_SAVEAVAS:
1348 case IDC_CONTENT_CONTEXT_SAVEIMAGEAS: {
1349 if (params_.media_type == WebContextMenuData::MediaTypeCanvas) {
1350 source_web_contents_->GetRenderViewHost()->SaveImageAt(
1351 params_.x, params_.y);
1353 // TODO(zino): We can use SaveImageAt() like a case of canvas.
1354 RecordDownloadSource(DOWNLOAD_INITIATED_BY_CONTEXT_MENU);
1355 const GURL& url = params_.src_url;
1356 const GURL& referring_url =
1357 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url;
1358 content::Referrer referrer = content::Referrer::SanitizeForRequest(
1360 content::Referrer(referring_url.GetAsReferrer(),
1361 params_.referrer_policy));
1362 source_web_contents_->SaveFrame(url, referrer);
1367 case IDC_CONTENT_CONTEXT_COPYLINKLOCATION:
1368 WriteURLToClipboard(params_.unfiltered_link_url);
1371 case IDC_CONTENT_CONTEXT_COPYIMAGELOCATION:
1372 case IDC_CONTENT_CONTEXT_COPYAVLOCATION:
1373 WriteURLToClipboard(params_.src_url);
1376 case IDC_CONTENT_CONTEXT_COPYIMAGE:
1377 CopyImageAt(params_.x, params_.y);
1380 case IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE:
1381 GetImageThumbnailForSearch();
1384 case IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB:
1385 case IDC_CONTENT_CONTEXT_OPENAVNEWTAB:
1388 params_.frame_url.is_empty() ? params_.page_url : params_.frame_url,
1389 NEW_BACKGROUND_TAB, content::PAGE_TRANSITION_LINK);
1392 case IDC_CONTENT_CONTEXT_PLAYPAUSE: {
1393 bool play = !!(params_.media_flags & WebContextMenuData::MediaPaused);
1395 content::RecordAction(UserMetricsAction("MediaContextMenu_Play"));
1397 content::RecordAction(UserMetricsAction("MediaContextMenu_Pause"));
1399 MediaPlayerActionAt(gfx::Point(params_.x, params_.y),
1400 WebMediaPlayerAction(
1401 WebMediaPlayerAction::Play, play));
1405 case IDC_CONTENT_CONTEXT_MUTE: {
1406 bool mute = !(params_.media_flags & WebContextMenuData::MediaMuted);
1408 content::RecordAction(UserMetricsAction("MediaContextMenu_Mute"));
1410 content::RecordAction(UserMetricsAction("MediaContextMenu_Unmute"));
1412 MediaPlayerActionAt(gfx::Point(params_.x, params_.y),
1413 WebMediaPlayerAction(
1414 WebMediaPlayerAction::Mute, mute));
1418 case IDC_CONTENT_CONTEXT_LOOP:
1419 content::RecordAction(UserMetricsAction("MediaContextMenu_Loop"));
1420 MediaPlayerActionAt(gfx::Point(params_.x, params_.y),
1421 WebMediaPlayerAction(
1422 WebMediaPlayerAction::Loop,
1423 !IsCommandIdChecked(IDC_CONTENT_CONTEXT_LOOP)));
1426 case IDC_CONTENT_CONTEXT_CONTROLS:
1427 content::RecordAction(UserMetricsAction("MediaContextMenu_Controls"));
1428 MediaPlayerActionAt(
1429 gfx::Point(params_.x, params_.y),
1430 WebMediaPlayerAction(
1431 WebMediaPlayerAction::Controls,
1432 !IsCommandIdChecked(IDC_CONTENT_CONTEXT_CONTROLS)));
1435 case IDC_CONTENT_CONTEXT_ROTATECW:
1436 content::RecordAction(
1437 UserMetricsAction("PluginContextMenu_RotateClockwise"));
1439 gfx::Point(params_.x, params_.y),
1441 WebPluginAction::Rotate90Clockwise,
1445 case IDC_CONTENT_CONTEXT_ROTATECCW:
1446 content::RecordAction(
1447 UserMetricsAction("PluginContextMenu_RotateCounterclockwise"));
1449 gfx::Point(params_.x, params_.y),
1451 WebPluginAction::Rotate90Counterclockwise,
1456 source_web_contents_->GetController().GoBack();
1460 source_web_contents_->GetController().GoForward();
1464 source_web_contents_->OnSavePage();
1468 source_web_contents_->GetController().Reload(true);
1471 case IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP: {
1472 const Extension* platform_app = GetExtension();
1473 DCHECK(platform_app);
1474 DCHECK(platform_app->is_platform_app());
1476 extensions::ExtensionSystem::Get(browser_context_)
1477 ->extension_service()
1478 ->ReloadExtension(platform_app->id());
1482 case IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP: {
1483 const Extension* platform_app = GetExtension();
1484 DCHECK(platform_app);
1485 DCHECK(platform_app->is_platform_app());
1487 apps::AppLoadService::Get(GetProfile())
1488 ->RestartApplication(platform_app->id());
1493 #if defined(ENABLE_PRINTING)
1494 if (params_.media_type == WebContextMenuData::MediaTypeNone) {
1495 #if defined(ENABLE_FULL_PRINTING)
1496 printing::PrintViewManager* print_view_manager =
1497 printing::PrintViewManager::FromWebContents(source_web_contents_);
1499 if (!print_view_manager)
1501 if (GetPrefs(browser_context_)
1502 ->GetBoolean(prefs::kPrintPreviewDisabled)) {
1503 print_view_manager->PrintNow();
1505 print_view_manager->PrintPreviewNow(!params_.selection_text.empty());
1508 printing::PrintViewManagerBasic* print_view_manager =
1509 printing::PrintViewManagerBasic::FromWebContents(
1510 source_web_contents_);
1511 if (!print_view_manager)
1513 print_view_manager->PrintNow();
1514 #endif // defined(ENABLE_FULL_PRINTING)
1516 if (render_frame_host) {
1517 render_frame_host->Send(new PrintMsg_PrintNodeUnderContextMenu(
1518 render_frame_host->GetRoutingID()));
1521 #endif // defined(ENABLE_PRINTING)
1524 case IDC_VIEW_SOURCE:
1525 source_web_contents_->ViewSource();
1528 case IDC_CONTENT_CONTEXT_INSPECTELEMENT:
1529 Inspect(params_.x, params_.y);
1532 case IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE: {
1533 const Extension* platform_app = GetExtension();
1534 DCHECK(platform_app);
1535 DCHECK(platform_app->is_platform_app());
1537 extensions::devtools_util::InspectBackgroundPage(platform_app,
1542 case IDC_CONTENT_CONTEXT_VIEWPAGEINFO: {
1543 NavigationController* controller = &source_web_contents_->GetController();
1544 // Important to use GetVisibleEntry to match what's showing in the
1545 // omnibox. This may return null.
1546 NavigationEntry* nav_entry = controller->GetVisibleEntry();
1550 chrome::FindBrowserWithWebContents(source_web_contents_);
1551 chrome::ShowWebsiteSettings(browser, source_web_contents_,
1552 nav_entry->GetURL(), nav_entry->GetSSL());
1556 case IDC_CONTENT_CONTEXT_TRANSLATE: {
1557 // A translation might have been triggered by the time the menu got
1558 // selected, do nothing in that case.
1559 ChromeTranslateClient* chrome_translate_client =
1560 ChromeTranslateClient::FromWebContents(source_web_contents_);
1561 if (!chrome_translate_client ||
1562 chrome_translate_client->GetLanguageState().IsPageTranslated() ||
1563 chrome_translate_client->GetLanguageState().translation_pending()) {
1566 std::string original_lang =
1567 chrome_translate_client->GetLanguageState().original_language();
1568 std::string target_lang = g_browser_process->GetApplicationLocale();
1570 translate::TranslateDownloadManager::GetLanguageCode(target_lang);
1571 // Since the user decided to translate for that language and site, clears
1572 // any preferences for not translating them.
1573 scoped_ptr<translate::TranslatePrefs> prefs(
1574 ChromeTranslateClient::CreateTranslatePrefs(
1575 GetPrefs(browser_context_)));
1576 prefs->UnblockLanguage(original_lang);
1577 prefs->RemoveSiteFromBlacklist(params_.page_url.HostNoBrackets());
1578 translate::TranslateManager* manager =
1579 chrome_translate_client->GetTranslateManager();
1581 manager->TranslatePage(original_lang, target_lang, true);
1585 case IDC_CONTENT_CONTEXT_RELOADFRAME:
1586 // We always obey the cache here.
1587 // TODO(evanm): Perhaps we could allow shift-clicking the menu item to do
1588 // a cache-ignoring reload of the frame.
1589 source_web_contents_->ReloadFocusedFrame(false);
1592 case IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE:
1593 source_web_contents_->ViewFrameSource(params_.frame_url,
1594 params_.frame_page_state);
1597 case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO: {
1598 Browser* browser = chrome::FindBrowserWithWebContents(
1599 source_web_contents_);
1600 chrome::ShowWebsiteSettings(browser, source_web_contents_,
1601 params_.frame_url, params_.security_info);
1605 case IDC_CONTENT_CONTEXT_UNDO:
1606 source_web_contents_->Undo();
1609 case IDC_CONTENT_CONTEXT_REDO:
1610 source_web_contents_->Redo();
1613 case IDC_CONTENT_CONTEXT_CUT:
1614 source_web_contents_->Cut();
1617 case IDC_CONTENT_CONTEXT_COPY:
1618 source_web_contents_->Copy();
1621 case IDC_CONTENT_CONTEXT_PASTE:
1622 source_web_contents_->Paste();
1625 case IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE:
1626 source_web_contents_->PasteAndMatchStyle();
1629 case IDC_CONTENT_CONTEXT_DELETE:
1630 source_web_contents_->Delete();
1633 case IDC_CONTENT_CONTEXT_SELECTALL:
1634 source_web_contents_->SelectAll();
1637 case IDC_CONTENT_CONTEXT_SEARCHWEBFOR:
1638 case IDC_CONTENT_CONTEXT_GOTOURL: {
1639 WindowOpenDisposition disposition =
1640 ForceNewTabDispositionFromEventFlags(event_flags);
1641 OpenURL(selection_navigation_url_, GURL(), disposition,
1642 content::PAGE_TRANSITION_LINK);
1645 case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS: {
1646 WindowOpenDisposition disposition =
1647 ForceNewTabDispositionFromEventFlags(event_flags);
1648 GURL url = chrome::GetSettingsUrl(chrome::kLanguageOptionsSubPage);
1649 OpenURL(url, GURL(), disposition, content::PAGE_TRANSITION_LINK);
1653 case IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_SETTINGS: {
1654 content::RecordAction(
1655 UserMetricsAction("RegisterProtocolHandler.ContextMenu_Settings"));
1656 WindowOpenDisposition disposition =
1657 ForceNewTabDispositionFromEventFlags(event_flags);
1658 GURL url = chrome::GetSettingsUrl(chrome::kHandlerSettingsSubPage);
1659 OpenURL(url, GURL(), disposition, content::PAGE_TRANSITION_LINK);
1663 case IDC_CONTENT_CONTEXT_ADDSEARCHENGINE: {
1664 // Make sure the model is loaded.
1665 TemplateURLService* model =
1666 TemplateURLServiceFactory::GetForProfile(GetProfile());
1671 SearchEngineTabHelper* search_engine_tab_helper =
1672 SearchEngineTabHelper::FromWebContents(source_web_contents_);
1673 if (search_engine_tab_helper &&
1674 search_engine_tab_helper->delegate()) {
1675 base::string16 keyword(TemplateURL::GenerateKeyword(params_.page_url));
1676 TemplateURLData data;
1677 data.short_name = keyword;
1678 data.SetKeyword(keyword);
1679 data.SetURL(params_.keyword_url.spec());
1681 TemplateURL::GenerateFaviconURL(params_.page_url.GetOrigin());
1682 // Takes ownership of the TemplateURL.
1683 search_engine_tab_helper->delegate()->ConfirmAddSearchProvider(
1684 new TemplateURL(data), GetProfile());
1695 ProtocolHandlerRegistry::ProtocolHandlerList
1696 RenderViewContextMenu::GetHandlersForLinkUrl() {
1697 ProtocolHandlerRegistry::ProtocolHandlerList handlers =
1698 protocol_handler_registry_->GetHandlersFor(params_.link_url.scheme());
1699 std::sort(handlers.begin(), handlers.end());
1703 void RenderViewContextMenu::NotifyMenuShown() {
1704 content::NotificationService::current()->Notify(
1705 chrome::NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_SHOWN,
1706 content::Source<RenderViewContextMenu>(this),
1707 content::NotificationService::NoDetails());
1710 void RenderViewContextMenu::NotifyURLOpened(
1712 content::WebContents* new_contents) {
1713 RetargetingDetails details;
1714 details.source_web_contents = source_web_contents_;
1715 details.source_render_frame_id = GetRenderFrameHost()->GetRoutingID();
1716 details.target_url = url;
1717 details.target_web_contents = new_contents;
1718 details.not_yet_in_tabstrip = false;
1720 content::NotificationService::current()->Notify(
1721 chrome::NOTIFICATION_RETARGETING,
1722 content::Source<Profile>(GetProfile()),
1723 content::Details<RetargetingDetails>(&details));
1726 bool RenderViewContextMenu::IsDevCommandEnabled(int id) const {
1727 if (id == IDC_CONTENT_CONTEXT_INSPECTELEMENT ||
1728 id == IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE) {
1729 const CommandLine* command_line = CommandLine::ForCurrentProcess();
1730 if (!GetPrefs(browser_context_)
1731 ->GetBoolean(prefs::kWebKitJavascriptEnabled) ||
1732 command_line->HasSwitch(switches::kDisableJavaScript))
1735 // Don't enable the web inspector if the developer tools are disabled via
1736 // the preference dev-tools-disabled.
1737 if (GetPrefs(browser_context_)->GetBoolean(prefs::kDevToolsDisabled))
1744 base::string16 RenderViewContextMenu::PrintableSelectionText() {
1745 return gfx::TruncateString(params_.selection_text,
1746 kMaxSelectionTextLength,
1750 // Controller functions --------------------------------------------------------
1752 void RenderViewContextMenu::CopyImageAt(int x, int y) {
1753 source_web_contents_->GetRenderViewHost()->CopyImageAt(x, y);
1756 void RenderViewContextMenu::GetImageThumbnailForSearch() {
1757 RenderFrameHost* render_frame_host = GetRenderFrameHost();
1758 if (!render_frame_host)
1760 render_frame_host->Send(new ChromeViewMsg_RequestThumbnailForContextNode(
1761 render_frame_host->GetRoutingID(),
1762 kImageSearchThumbnailMinSize,
1763 gfx::Size(kImageSearchThumbnailMaxWidth,
1764 kImageSearchThumbnailMaxHeight)));
1767 void RenderViewContextMenu::Inspect(int x, int y) {
1768 content::RecordAction(UserMetricsAction("DevTools_InspectElement"));
1769 RenderFrameHost* render_frame_host = GetRenderFrameHost();
1770 if (!render_frame_host)
1772 DevToolsWindow::InspectElement(
1773 WebContents::FromRenderFrameHost(render_frame_host), x, y);
1776 void RenderViewContextMenu::WriteURLToClipboard(const GURL& url) {
1777 chrome_common_net::WriteURLToClipboard(
1779 GetPrefs(browser_context_)->GetString(prefs::kAcceptLanguages),
1780 ui::Clipboard::GetForCurrentThread());
1783 void RenderViewContextMenu::MediaPlayerActionAt(
1784 const gfx::Point& location,
1785 const WebMediaPlayerAction& action) {
1786 source_web_contents_->GetRenderViewHost()->
1787 ExecuteMediaPlayerActionAtLocation(location, action);
1790 void RenderViewContextMenu::PluginActionAt(
1791 const gfx::Point& location,
1792 const WebPluginAction& action) {
1793 source_web_contents_->GetRenderViewHost()->
1794 ExecutePluginActionAtLocation(location, action);