Home | History | Annotate | Download | only in shell
      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 #import  <Cocoa/Cocoa.h>
      8 
      9 #include "base/command_line.h"
     10 #include "content/public/browser/render_process_host.h"
     11 #include "content/public/browser/render_view_host.h"
     12 #include "content/public/browser/render_widget_host_view.h"
     13 #include "content/public/browser/web_contents.h"
     14 #include "content/public/browser/web_contents_view.h"
     15 #include "content/public/common/context_menu_params.h"
     16 #include "content/shell/common/shell_switches.h"
     17 #include "content/shell/shell.h"
     18 #include "content/shell/shell_browser_context.h"
     19 #include "content/shell/shell_browser_main_parts.h"
     20 #include "content/shell/shell_content_browser_client.h"
     21 #include "content/shell/shell_devtools_frontend.h"
     22 #include "content/shell/shell_web_contents_view_delegate_creator.h"
     23 #include "third_party/WebKit/public/web/WebContextMenuData.h"
     24 
     25 using WebKit::WebContextMenuData;
     26 
     27 enum {
     28   ShellContextMenuItemCutTag = 0,
     29   ShellContextMenuItemCopyTag,
     30   ShellContextMenuItemPasteTag,
     31   ShellContextMenuItemDeleteTag,
     32   ShellContextMenuItemOpenLinkTag,
     33   ShellContextMenuItemBackTag,
     34   ShellContextMenuItemForwardTag,
     35   ShellContextMenuItemReloadTag,
     36   ShellContextMenuItemInspectTag
     37 };
     38 
     39 @interface ShellContextMenuDelegate : NSObject<NSMenuDelegate> {
     40  @private
     41   content::ShellWebContentsViewDelegate* delegate_;
     42 }
     43 @end
     44 
     45 @implementation ShellContextMenuDelegate
     46 - (id)initWithDelegate:(content::ShellWebContentsViewDelegate*) delegate {
     47   if ((self = [super init])) {
     48     delegate_ = delegate;
     49   }
     50   return self;
     51 }
     52 
     53 - (void)itemSelected:(id)sender {
     54   NSInteger tag = [sender tag];
     55   delegate_->ActionPerformed(tag);
     56 }
     57 @end
     58 
     59 namespace {
     60 
     61 NSMenuItem* MakeContextMenuItem(NSString* title,
     62                                 NSInteger tag,
     63                                 NSMenu* menu,
     64                                 BOOL enabled,
     65                                 ShellContextMenuDelegate* delegate) {
     66   NSMenuItem* menu_item =
     67       [[NSMenuItem alloc] initWithTitle:title
     68                                  action:@selector(itemSelected:)
     69                           keyEquivalent:@""];
     70   [menu_item setTarget:delegate];
     71   [menu_item setTag:tag];
     72   [menu_item setEnabled:enabled];
     73   [menu addItem:menu_item];
     74 
     75   return menu_item;
     76 }
     77 
     78 }  // namespace
     79 
     80 namespace content {
     81 
     82 WebContentsViewDelegate* CreateShellWebContentsViewDelegate(
     83   WebContents* web_contents) {
     84   return new ShellWebContentsViewDelegate(web_contents);
     85 }
     86 
     87 ShellWebContentsViewDelegate::ShellWebContentsViewDelegate(
     88     WebContents* web_contents)
     89     : web_contents_(web_contents) {
     90 }
     91 
     92 ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() {
     93 }
     94 
     95 void ShellWebContentsViewDelegate::ShowContextMenu(
     96     const ContextMenuParams& params) {
     97   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
     98     return;
     99 
    100   params_ = params;
    101   bool has_link = !params_.unfiltered_link_url.is_empty();
    102   bool has_selection = ! params_.selection_text.empty();
    103 
    104   NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
    105   ShellContextMenuDelegate* delegate =
    106       [[ShellContextMenuDelegate alloc] initWithDelegate:this];
    107   [menu setDelegate:delegate];
    108   [menu setAutoenablesItems:NO];
    109 
    110   if (params.media_type == WebContextMenuData::MediaTypeNone &&
    111       !has_link &&
    112       !has_selection &&
    113       !params_.is_editable) {
    114     BOOL back_menu_enabled =
    115         web_contents_->GetController().CanGoBack() ? YES : NO;
    116     MakeContextMenuItem(@"Back",
    117                         ShellContextMenuItemBackTag,
    118                         menu,
    119                         back_menu_enabled,
    120                         delegate);
    121 
    122     BOOL forward_menu_enabled =
    123         web_contents_->GetController().CanGoForward() ? YES : NO;
    124     MakeContextMenuItem(@"Forward",
    125                         ShellContextMenuItemForwardTag,
    126                         menu,
    127                         forward_menu_enabled,
    128                         delegate);
    129 
    130     MakeContextMenuItem(@"Reload",
    131                         ShellContextMenuItemReloadTag,
    132                         menu,
    133                         YES,
    134                         delegate);
    135 
    136     NSMenuItem* separator = [NSMenuItem separatorItem];
    137     [menu addItem:separator];
    138   }
    139 
    140   if (has_link) {
    141     MakeContextMenuItem(@"Open In New Window",
    142                         ShellContextMenuItemOpenLinkTag,
    143                         menu,
    144                         YES,
    145                         delegate);
    146 
    147     NSMenuItem* separator = [NSMenuItem separatorItem];
    148     [menu addItem:separator];
    149   }
    150 
    151   if (params_.is_editable) {
    152     BOOL cut_menu_enabled =
    153         (params_.edit_flags & WebContextMenuData::CanCut) ? YES : NO;
    154     MakeContextMenuItem(@"Cut",
    155                         ShellContextMenuItemCutTag,
    156                         menu,
    157                         cut_menu_enabled,
    158                         delegate);
    159 
    160     BOOL copy_menu_enabled =
    161         (params_.edit_flags & WebContextMenuData::CanCopy) ? YES : NO;
    162     MakeContextMenuItem(@"Copy",
    163                         ShellContextMenuItemCopyTag,
    164                         menu,
    165                         copy_menu_enabled,
    166                         delegate);
    167 
    168     BOOL paste_menu_enabled =
    169         (params_.edit_flags & WebContextMenuData::CanPaste) ? YES : NO;
    170     MakeContextMenuItem(@"Paste",
    171                         ShellContextMenuItemPasteTag,
    172                         menu,
    173                         paste_menu_enabled,
    174                         delegate);
    175 
    176     BOOL delete_menu_enabled =
    177         (params_.edit_flags & WebContextMenuData::CanDelete) ? YES : NO;
    178     MakeContextMenuItem(@"Delete",
    179                         ShellContextMenuItemDeleteTag,
    180                         menu,
    181                         delete_menu_enabled,
    182                         delegate);
    183 
    184     NSMenuItem* separator = [NSMenuItem separatorItem];
    185     [menu addItem:separator];
    186   } else if (has_selection) {
    187     MakeContextMenuItem(@"Copy",
    188                         ShellContextMenuItemCopyTag,
    189                         menu,
    190                         YES,
    191                         delegate);
    192 
    193     NSMenuItem* separator = [NSMenuItem separatorItem];
    194     [menu addItem:separator];
    195   }
    196 
    197   MakeContextMenuItem(@"Inspect",
    198                       ShellContextMenuItemInspectTag,
    199                       menu,
    200                       YES,
    201                       delegate);
    202 
    203   NSView* parent_view = web_contents_->GetView()->GetContentNativeView();
    204   NSEvent* currentEvent = [NSApp currentEvent];
    205   NSWindow* window = [parent_view window];
    206   NSPoint position = [window mouseLocationOutsideOfEventStream];
    207   NSTimeInterval eventTime = [currentEvent timestamp];
    208   NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
    209                                            location:position
    210                                       modifierFlags:NSRightMouseDownMask
    211                                           timestamp:eventTime
    212                                        windowNumber:[window windowNumber]
    213                                             context:nil
    214                                         eventNumber:0
    215                                          clickCount:1
    216                                            pressure:1.0];
    217 
    218   [NSMenu popUpContextMenu:menu
    219                  withEvent:clickEvent
    220                    forView:parent_view];
    221 }
    222 
    223 void ShellWebContentsViewDelegate::ActionPerformed(int tag) {
    224   switch (tag) {
    225     case ShellContextMenuItemCutTag:
    226       web_contents_->GetRenderViewHost()->Cut();
    227       break;
    228     case ShellContextMenuItemCopyTag:
    229       web_contents_->GetRenderViewHost()->Copy();
    230       break;
    231     case ShellContextMenuItemPasteTag:
    232       web_contents_->GetRenderViewHost()->Paste();
    233       break;
    234     case ShellContextMenuItemDeleteTag:
    235       web_contents_->GetRenderViewHost()->Delete();
    236       break;
    237     case ShellContextMenuItemOpenLinkTag: {
    238       ShellBrowserContext* browser_context =
    239           ShellContentBrowserClient::Get()->browser_context();
    240       Shell::CreateNewWindow(browser_context,
    241                              params_.link_url,
    242                              NULL,
    243                              MSG_ROUTING_NONE,
    244                              gfx::Size());
    245       break;
    246     }
    247     case ShellContextMenuItemBackTag:
    248       web_contents_->GetController().GoToOffset(-1);
    249       web_contents_->GetView()->Focus();
    250       break;
    251     case ShellContextMenuItemForwardTag:
    252       web_contents_->GetController().GoToOffset(1);
    253       web_contents_->GetView()->Focus();
    254       break;
    255     case ShellContextMenuItemReloadTag: {
    256       web_contents_->GetController().Reload(false);
    257       web_contents_->GetView()->Focus();
    258       break;
    259     }
    260     case ShellContextMenuItemInspectTag: {
    261       ShellDevToolsFrontend::Show(web_contents_);
    262       break;
    263     }
    264   }
    265 }
    266 
    267 WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
    268   return NULL;
    269 }
    270 
    271 NSObject<RenderWidgetHostViewMacDelegate>*
    272 ShellWebContentsViewDelegate::CreateRenderWidgetHostViewDelegate(
    273     content::RenderWidgetHost* render_widget_host) {
    274   return NULL;
    275 }
    276 
    277 }  // namespace content
    278