1 // Copyright 2013 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/browser/shell_web_contents_view_delegate.h" 6 7 #include "base/command_line.h" 8 #include "content/public/browser/render_frame_host.h" 9 #include "content/public/browser/render_process_host.h" 10 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/render_widget_host_view.h" 12 #include "content/public/browser/web_contents.h" 13 #include "content/public/common/context_menu_params.h" 14 #include "content/shell/browser/shell.h" 15 #include "content/shell/browser/shell_browser_context.h" 16 #include "content/shell/browser/shell_browser_main_parts.h" 17 #include "content/shell/browser/shell_content_browser_client.h" 18 #include "content/shell/browser/shell_devtools_frontend.h" 19 #include "content/shell/browser/shell_web_contents_view_delegate_creator.h" 20 #include "content/shell/common/shell_switches.h" 21 #include "third_party/WebKit/public/web/WebContextMenuData.h" 22 23 using blink::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 LPCTSTR 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 = const_cast<LPTSTR>(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 RenderFrameHost* render_frame_host, 74 const ContextMenuParams& params) { 75 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) 76 return; 77 78 params_ = params; 79 bool has_link = !params_.unfiltered_link_url.is_empty(); 80 bool has_selection = !params_.selection_text.empty(); 81 82 HMENU menu = CreateMenu(); 83 HMENU sub_menu = CreatePopupMenu(); 84 AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)sub_menu, L""); 85 86 int index = 0; 87 if (params_.media_type == WebContextMenuData::MediaTypeNone && 88 !has_link && 89 !has_selection && 90 !params_.is_editable) { 91 MakeContextMenuItem(sub_menu, 92 index++, 93 L"Back", 94 ShellContextMenuItemBackId, 95 web_contents_->GetController().CanGoBack()); 96 97 MakeContextMenuItem(sub_menu, 98 index++, 99 L"Forward", 100 ShellContextMenuItemForwardId, 101 web_contents_->GetController().CanGoForward()); 102 103 MakeContextMenuItem(sub_menu, 104 index++, 105 L"Reload", 106 ShellContextMenuItemReloadId, 107 true); 108 109 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 110 index++; 111 } 112 113 if (has_link) { 114 MakeContextMenuItem(sub_menu, 115 index++, 116 L"Open in New Window", 117 ShellContextMenuItemOpenLinkId, 118 true); 119 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 120 index++; 121 } 122 123 if (params_.is_editable) { 124 bool cut_enabled = ((params_.edit_flags & WebContextMenuData::CanCut) != 0); 125 MakeContextMenuItem(sub_menu, 126 index++, 127 L"Cut", 128 ShellContextMenuItemCutId, 129 cut_enabled); 130 131 bool copy_enabled = 132 ((params_.edit_flags & WebContextMenuData::CanCopy) != 0); 133 MakeContextMenuItem(sub_menu, 134 index++, 135 L"Copy", 136 ShellContextMenuItemCopyId, 137 copy_enabled); 138 139 bool paste_enabled = 140 ((params_.edit_flags & WebContextMenuData::CanPaste) != 0); 141 MakeContextMenuItem(sub_menu, 142 index++, 143 L"Paste", 144 ShellContextMenuItemPasteId, 145 paste_enabled); 146 bool delete_enabled = 147 ((params_.edit_flags & WebContextMenuData::CanDelete) != 0); 148 MakeContextMenuItem(sub_menu, 149 index++, 150 L"Delete", 151 ShellContextMenuItemDeleteId, 152 delete_enabled); 153 154 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 155 index++; 156 } else if (has_selection) { 157 MakeContextMenuItem(sub_menu, 158 index++, 159 L"Copy", 160 ShellContextMenuItemCopyId, 161 true); 162 163 AppendMenu(sub_menu, MF_SEPARATOR, 0, NULL); 164 index++; 165 } 166 167 MakeContextMenuItem(sub_menu, 168 index++, 169 L"Inspect...", 170 ShellContextMenuItemInspectId, 171 true); 172 #if defined(USE_AURA) 173 NOTIMPLEMENTED(); 174 #else 175 gfx::Point screen_point(params.x, params.y); 176 POINT point = screen_point.ToPOINT(); 177 ClientToScreen(web_contents_->GetNativeView(), &point); 178 179 int selection = 180 TrackPopupMenu(sub_menu, 181 TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, 182 point.x, point.y, 183 0, 184 web_contents_->GetContentNativeView(), 185 NULL); 186 187 MenuItemSelected(selection); 188 #endif 189 DestroyMenu(menu); 190 } 191 192 void ShellWebContentsViewDelegate::MenuItemSelected(int selection) { 193 switch (selection) { 194 case ShellContextMenuItemCutId: 195 web_contents_->Cut(); 196 break; 197 case ShellContextMenuItemCopyId: 198 web_contents_->Copy(); 199 break; 200 case ShellContextMenuItemPasteId: 201 web_contents_->Paste(); 202 break; 203 case ShellContextMenuItemDeleteId: 204 web_contents_->Delete(); 205 break; 206 case ShellContextMenuItemOpenLinkId: { 207 ShellBrowserContext* browser_context = 208 ShellContentBrowserClient::Get()->browser_context(); 209 Shell::CreateNewWindow(browser_context, 210 params_.link_url, 211 NULL, 212 MSG_ROUTING_NONE, 213 gfx::Size()); 214 break; 215 } 216 case ShellContextMenuItemBackId: 217 web_contents_->GetController().GoToOffset(-1); 218 web_contents_->Focus(); 219 break; 220 case ShellContextMenuItemForwardId: 221 web_contents_->GetController().GoToOffset(1); 222 web_contents_->Focus(); 223 break; 224 case ShellContextMenuItemReloadId: 225 web_contents_->GetController().Reload(false); 226 web_contents_->Focus(); 227 break; 228 case ShellContextMenuItemInspectId: { 229 ShellDevToolsFrontend::Show(web_contents_); 230 break; 231 } 232 } 233 } 234 235 #if defined(TOOLKIT_VIEWS) 236 void ShellWebContentsViewDelegate::ShowDisambiguationPopup( 237 const gfx::Rect& target_rect, 238 const SkBitmap& zoomed_bitmap, 239 const gfx::NativeView content, 240 const base::Callback<void(ui::GestureEvent*)>& gesture_cb, 241 const base::Callback<void(ui::MouseEvent*)>& mouse_cb) { 242 } 243 244 void ShellWebContentsViewDelegate::HideDisambiguationPopup() { 245 } 246 #endif 247 248 } // namespace content 249