1 // Copyright (c) 2012 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 "content/shell/shell_web_contents_view_delegate.h" 6 7 #include "base/command_line.h" 8 #include "content/public/browser/render_process_host.h" 9 #include "content/public/browser/render_view_host.h" 10 #include "content/public/browser/render_widget_host_view.h" 11 #include "content/public/browser/web_contents.h" 12 #include "content/public/browser/web_contents_view.h" 13 #include "content/public/common/context_menu_params.h" 14 #include "content/shell/common/shell_switches.h" 15 #include "content/shell/shell.h" 16 #include "content/shell/shell_browser_context.h" 17 #include "content/shell/shell_browser_main_parts.h" 18 #include "content/shell/shell_content_browser_client.h" 19 #include "content/shell/shell_devtools_frontend.h" 20 #include "content/shell/shell_web_contents_view_delegate_creator.h" 21 #include "third_party/WebKit/public/web/WebContextMenuData.h" 22 23 using WebKit::WebContextMenuData; 24 25 namespace { 26 27 enum { 28 ShellContextMenuItemCutId = 10001, 29 ShellContextMenuItemCopyId, 30 ShellContextMenuItemPasteId, 31 ShellContextMenuItemDeleteId, 32 ShellContextMenuItemOpenLinkId, 33 ShellContextMenuItemBackId, 34 ShellContextMenuItemForwardId, 35 ShellContextMenuItemReloadId, 36 ShellContextMenuItemInspectId 37 }; 38 39 void MakeContextMenuItem(HMENU menu, 40 int menu_index, 41 LPTSTR text, 42 UINT id, 43 bool enabled) { 44 MENUITEMINFO mii = {0}; 45 mii.cbSize = sizeof(mii); 46 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA | MIIM_STRING | MIIM_STATE; 47 mii.fState = enabled ? MFS_ENABLED : (MF_DISABLED | MFS_GRAYED); 48 mii.fType = MFT_STRING; 49 mii.wID = id; 50 mii.dwTypeData = text; 51 52 InsertMenuItem(menu, menu_index, TRUE, &mii); 53 } 54 55 } // namespace 56 57 namespace content { 58 59 WebContentsViewDelegate* CreateShellWebContentsViewDelegate( 60 WebContents* web_contents) { 61 return new ShellWebContentsViewDelegate(web_contents); 62 } 63 64 ShellWebContentsViewDelegate::ShellWebContentsViewDelegate( 65 WebContents* web_contents) 66 : web_contents_(web_contents) { 67 } 68 69 ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() { 70 } 71 72 void ShellWebContentsViewDelegate::ShowContextMenu( 73 const ContextMenuParams& params) { 74 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) 75 return; 76 77 params_ = params; 78 bool has_link = !params_.unfiltered_link_url.is_empty(); 79 bool has_selection = !params_.selection_text.empty(); 80 81 HMENU menu = CreateMenu(); 82 HMENU sub_menu = CreatePopupMenu(); 83 AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)sub_menu, L""); 84 85 int index = 0; 86 if (params_.media_type == WebContextMenuData::MediaTypeNone && 87 !has_link && 88 !has_selection && 89 !params_.is_editable) { 90 MakeContextMenuItem(sub_menu, 91 index++, 92 L"Back", 93 ShellContextMenuItemBackId, 94 web_contents_->GetController().CanGoBack()); 95 96 MakeContextMenuItem(sub_menu, 97 index++, 98 L"Forward", 99 ShellContextMenuItemForwardId, 100 web_contents_->GetController().CanGoForward()); 101 102 MakeContextMenuItem(sub_menu, 103 index++, 104 L"Reload", 105 ShellContextMenuItemReloadId, 106 true); 107 108 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 109 index++; 110 } 111 112 if (has_link) { 113 MakeContextMenuItem(sub_menu, 114 index++, 115 L"Open in New Window", 116 ShellContextMenuItemOpenLinkId, 117 true); 118 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 119 index++; 120 } 121 122 if (params_.is_editable) { 123 bool cut_enabled = ((params_.edit_flags & WebContextMenuData::CanCut) != 0); 124 MakeContextMenuItem(sub_menu, 125 index++, 126 L"Cut", 127 ShellContextMenuItemCutId, 128 cut_enabled); 129 130 bool copy_enabled = 131 ((params_.edit_flags & WebContextMenuData::CanCopy) != 0); 132 MakeContextMenuItem(sub_menu, 133 index++, 134 L"Copy", 135 ShellContextMenuItemCopyId, 136 copy_enabled); 137 138 bool paste_enabled = 139 ((params_.edit_flags & WebContextMenuData::CanPaste) != 0); 140 MakeContextMenuItem(sub_menu, 141 index++, 142 L"Paste", 143 ShellContextMenuItemPasteId, 144 paste_enabled); 145 bool delete_enabled = 146 ((params_.edit_flags & WebContextMenuData::CanDelete) != 0); 147 MakeContextMenuItem(sub_menu, 148 index++, 149 L"Delete", 150 ShellContextMenuItemDeleteId, 151 delete_enabled); 152 153 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 154 index++; 155 } else if (has_selection) { 156 MakeContextMenuItem(sub_menu, 157 index++, 158 L"Copy", 159 ShellContextMenuItemCopyId, 160 true); 161 162 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 163 index++; 164 } 165 166 MakeContextMenuItem(sub_menu, 167 index++, 168 L"Inspect...", 169 ShellContextMenuItemInspectId, 170 true); 171 #if defined(USE_AURA) 172 NOTIMPLEMENTED(); 173 #else 174 gfx::Point screen_point(params.x, params.y); 175 POINT point = screen_point.ToPOINT(); 176 ClientToScreen(web_contents_->GetView()->GetNativeView(), &point); 177 178 int selection = 179 TrackPopupMenu(sub_menu, 180 TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, 181 point.x, point.y, 182 0, 183 web_contents_->GetView()->GetContentNativeView(), 184 NULL); 185 186 MenuItemSelected(selection); 187 #endif 188 DestroyMenu(menu); 189 } 190 191 void ShellWebContentsViewDelegate::MenuItemSelected(int selection) { 192 switch (selection) { 193 case ShellContextMenuItemCutId: 194 web_contents_->GetRenderViewHost()->Cut(); 195 break; 196 case ShellContextMenuItemCopyId: 197 web_contents_->GetRenderViewHost()->Copy(); 198 break; 199 case ShellContextMenuItemPasteId: 200 web_contents_->GetRenderViewHost()->Paste(); 201 break; 202 case ShellContextMenuItemDeleteId: 203 web_contents_->GetRenderViewHost()->Delete(); 204 break; 205 case ShellContextMenuItemOpenLinkId: { 206 ShellBrowserContext* browser_context = 207 ShellContentBrowserClient::Get()->browser_context(); 208 Shell::CreateNewWindow(browser_context, 209 params_.link_url, 210 NULL, 211 MSG_ROUTING_NONE, 212 gfx::Size()); 213 break; 214 } 215 case ShellContextMenuItemBackId: 216 web_contents_->GetController().GoToOffset(-1); 217 web_contents_->GetView()->Focus(); 218 break; 219 case ShellContextMenuItemForwardId: 220 web_contents_->GetController().GoToOffset(1); 221 web_contents_->GetView()->Focus(); 222 break; 223 case ShellContextMenuItemReloadId: 224 web_contents_->GetController().Reload(false); 225 web_contents_->GetView()->Focus(); 226 break; 227 case ShellContextMenuItemInspectId: { 228 ShellDevToolsFrontend::Show(web_contents_); 229 break; 230 } 231 } 232 } 233 234 WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() { 235 return NULL; 236 } 237 238 void ShellWebContentsViewDelegate::StoreFocus() { 239 } 240 241 void ShellWebContentsViewDelegate::RestoreFocus() { 242 } 243 244 bool ShellWebContentsViewDelegate::Focus() { 245 return false; 246 } 247 248 void ShellWebContentsViewDelegate::TakeFocus(bool reverse) { 249 } 250 251 void ShellWebContentsViewDelegate::SizeChanged(const gfx::Size& size) { 252 } 253 254 } // namespace content 255