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. 4 5 #include "chrome/browser/renderer_context_menu/context_menu_content_type.h" 6 7 #include "chrome/app/chrome_command_ids.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile_io_data.h" 10 #include "chrome/common/url_constants.h" 11 #include "content/public/browser/web_contents.h" 12 #include "content/public/common/url_constants.h" 13 #include "extensions/browser/extension_system.h" 14 #include "extensions/browser/process_manager.h" 15 #include "extensions/common/extension.h" 16 #include "third_party/WebKit/public/web/WebContextMenuData.h" 17 18 19 using blink::WebContextMenuData; 20 using content::WebContents; 21 using extensions::Extension; 22 23 namespace { 24 25 bool IsDevToolsURL(const GURL& url) { 26 return url.SchemeIs(content::kChromeDevToolsScheme); 27 } 28 29 bool IsInternalResourcesURL(const GURL& url) { 30 return url.SchemeIs(content::kChromeUIScheme) && 31 (url.host() == chrome::kChromeUISyncResourcesHost); 32 } 33 34 } // namespace 35 36 ContextMenuContentType::ContextMenuContentType( 37 content::WebContents* web_contents, 38 const content::ContextMenuParams& params, 39 bool supports_custom_items) 40 : params_(params), 41 source_web_contents_(web_contents), 42 profile_(Profile::FromBrowserContext( 43 source_web_contents_->GetBrowserContext())), 44 supports_custom_items_(supports_custom_items) { 45 } 46 47 ContextMenuContentType::~ContextMenuContentType() { 48 } 49 50 const Extension* ContextMenuContentType::GetExtension() const { 51 extensions::ExtensionSystem* system = 52 extensions::ExtensionSystem::Get(profile_); 53 // There is no process manager in some tests. 54 if (!system->process_manager()) 55 return NULL; 56 57 return system->process_manager()->GetExtensionForRenderViewHost( 58 source_web_contents_->GetRenderViewHost()); 59 } 60 61 bool ContextMenuContentType::SupportsGroup(int group) { 62 const bool has_selection = !params_.selection_text.empty(); 63 64 if (supports_custom_items_ && !params_.custom_items.empty()) { 65 if (group == ITEM_GROUP_CUSTOM) 66 return true; 67 68 if (!has_selection) { 69 // For menus with custom items, if there is no selection, we do not 70 // add items other than developer items. And for Pepper menu, don't even 71 // add developer items. 72 if (!params_.custom_context.is_pepper_menu) 73 return group == ITEM_GROUP_DEVELOPER; 74 75 return false; 76 } 77 78 // If there's a selection when there are custom items, fall through to 79 // adding the normal ones after the custom ones. 80 } 81 82 return SupportsGroupInternal(group); 83 } 84 85 bool ContextMenuContentType::SupportsGroupInternal(int group) { 86 const bool has_link = !params_.unfiltered_link_url.is_empty(); 87 const bool has_selection = !params_.selection_text.empty(); 88 89 switch (group) { 90 case ITEM_GROUP_CUSTOM: 91 return supports_custom_items_ && !params_.custom_items.empty(); 92 93 case ITEM_GROUP_PAGE: { 94 bool is_candidate = 95 params_.media_type == WebContextMenuData::MediaTypeNone && 96 !has_link && !params_.is_editable && !has_selection; 97 98 if (!is_candidate && params_.page_url.is_empty()) 99 DCHECK(params_.frame_url.is_empty()); 100 101 return is_candidate && !params_.page_url.is_empty() && 102 !IsDevToolsURL(params_.page_url) && 103 !IsInternalResourcesURL(params_.page_url); 104 } 105 106 case ITEM_GROUP_FRAME: { 107 108 bool page_group_supported = SupportsGroupInternal(ITEM_GROUP_PAGE); 109 return page_group_supported && !params_.frame_url.is_empty() && 110 !IsDevToolsURL(params_.frame_url) && 111 !IsInternalResourcesURL(params_.page_url); 112 } 113 114 case ITEM_GROUP_LINK: 115 return has_link; 116 117 case ITEM_GROUP_MEDIA_IMAGE: 118 return params_.media_type == WebContextMenuData::MediaTypeImage; 119 120 case ITEM_GROUP_SEARCHWEBFORIMAGE: 121 // Image menu items imply search web for image item. 122 return SupportsGroupInternal(ITEM_GROUP_MEDIA_IMAGE); 123 124 case ITEM_GROUP_MEDIA_VIDEO: 125 return params_.media_type == WebContextMenuData::MediaTypeVideo; 126 127 case ITEM_GROUP_MEDIA_AUDIO: 128 return params_.media_type == WebContextMenuData::MediaTypeAudio; 129 130 case ITEM_GROUP_MEDIA_CANVAS: 131 return params_.media_type == WebContextMenuData::MediaTypeCanvas; 132 133 case ITEM_GROUP_MEDIA_PLUGIN: 134 return params_.media_type == WebContextMenuData::MediaTypePlugin; 135 136 case ITEM_GROUP_MEDIA_FILE: 137 #if defined(WEBCONTEXT_MEDIATYPEFILE_DEFINED) 138 return params_.media_type == WebContextMenuData::MediaTypeFile; 139 #else 140 return false; 141 #endif 142 143 case ITEM_GROUP_EDITABLE: 144 return params_.is_editable; 145 146 case ITEM_GROUP_COPY: 147 return !params_.is_editable && has_selection; 148 149 case ITEM_GROUP_SEARCH_PROVIDER: 150 return has_selection; 151 152 case ITEM_GROUP_PRINT: { 153 bool enable = has_selection && !IsDevToolsURL(params_.page_url); 154 // Image menu items also imply print items. 155 return enable || SupportsGroupInternal(ITEM_GROUP_MEDIA_IMAGE); 156 } 157 158 case ITEM_GROUP_ALL_EXTENSION: 159 return !IsDevToolsURL(params_.page_url); 160 161 case ITEM_GROUP_CURRENT_EXTENSION: 162 return false; 163 164 case ITEM_GROUP_DEVELOPER: 165 return true; 166 167 case ITEM_GROUP_DEVTOOLS_UNPACKED_EXT: 168 return false; 169 170 case ITEM_GROUP_PRINT_PREVIEW: 171 #if defined(ENABLE_FULL_PRINTING) 172 return true; 173 #else 174 return false; 175 #endif 176 177 default: 178 NOTREACHED(); 179 return false; 180 } 181 } 182