Home | History | Annotate | Download | only in browser
      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                          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     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 WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
    236   return NULL;
    237 }
    238 
    239 void ShellWebContentsViewDelegate::StoreFocus() {
    240 }
    241 
    242 void ShellWebContentsViewDelegate::RestoreFocus() {
    243 }
    244 
    245 bool ShellWebContentsViewDelegate::Focus() {
    246   return false;
    247 }
    248 
    249 void ShellWebContentsViewDelegate::TakeFocus(bool reverse) {
    250 }
    251 
    252 void ShellWebContentsViewDelegate::SizeChanged(const gfx::Size& size) {
    253 }
    254 
    255 }  // namespace content
    256