Home | History | Annotate | Download | only in content
      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 "athena/content/public/web_contents_view_delegate_creator.h"
      6 
      7 #include "athena/content/render_view_context_menu_impl.h"
      8 #include "components/web_modal/popup_manager.h"
      9 #include "components/web_modal/single_web_contents_dialog_manager.h"
     10 #include "components/web_modal/web_contents_modal_dialog_host.h"
     11 #include "components/web_modal/web_contents_modal_dialog_manager.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_delegate.h"
     15 #include "content/public/browser/web_contents_view_delegate.h"
     16 #include "ui/aura/client/screen_position_client.h"
     17 #include "ui/aura/window.h"
     18 #include "ui/views/widget/widget.h"
     19 
     20 namespace athena {
     21 namespace {
     22 
     23 class WebContentsViewDelegateImpl : public content::WebContentsViewDelegate {
     24  public:
     25   explicit WebContentsViewDelegateImpl(content::WebContents* web_contents)
     26       : web_contents_(web_contents) {}
     27   virtual ~WebContentsViewDelegateImpl() {}
     28 
     29   virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE {
     30     // TODO(oshima): crbug.com/401610
     31     return NULL;
     32   }
     33 
     34   virtual bool Focus() OVERRIDE {
     35     web_modal::PopupManager* popup_manager =
     36         web_modal::PopupManager::FromWebContents(web_contents_);
     37     if (popup_manager)
     38       popup_manager->WasFocused(web_contents_);
     39     return false;
     40   }
     41 
     42   virtual void ShowContextMenu(
     43       content::RenderFrameHost* render_frame_host,
     44       const content::ContextMenuParams& params) OVERRIDE {
     45     ShowMenu(BuildMenu(
     46         content::WebContents::FromRenderFrameHost(render_frame_host), params));
     47   }
     48 
     49   virtual void SizeChanged(const gfx::Size& size) OVERRIDE {
     50     // TODO(oshima|sadrul): Implement this when sad_tab is componentized.
     51     // See c/b/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
     52   }
     53 
     54   virtual void ShowDisambiguationPopup(
     55       const gfx::Rect& target_rect,
     56       const SkBitmap& zoomed_bitmap,
     57       const gfx::NativeView content,
     58       const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
     59       const base::Callback<void(ui::MouseEvent*)>& mouse_cb) OVERRIDE {
     60   }
     61 
     62   virtual void HideDisambiguationPopup() OVERRIDE {
     63   }
     64 
     65   scoped_ptr<RenderViewContextMenuImpl> BuildMenu(
     66       content::WebContents* web_contents,
     67       const content::ContextMenuParams& params) {
     68     scoped_ptr<RenderViewContextMenuImpl> menu;
     69     content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
     70     // If the frame tree does not have a focused frame at this point, do not
     71     // bother creating RenderViewContextMenuViews.
     72     // This happens if the frame has navigated to a different page before
     73     // ContextMenu message was received by the current RenderFrameHost.
     74     if (focused_frame) {
     75       menu.reset(new RenderViewContextMenuImpl(focused_frame, params));
     76       menu->Init();
     77     }
     78     return menu.Pass();
     79   }
     80 
     81   void ShowMenu(scoped_ptr<RenderViewContextMenuImpl> menu) {
     82     context_menu_.reset(menu.release());
     83 
     84     if (!context_menu_.get())
     85       return;
     86 
     87     // Menus need a Widget to work. If we're not the active tab we won't
     88     // necessarily be in a widget.
     89     views::Widget* top_level_widget = GetTopLevelWidget();
     90     if (!top_level_widget)
     91       return;
     92 
     93     const content::ContextMenuParams& params = context_menu_->params();
     94     // Don't show empty menus.
     95     if (context_menu_->menu_model().GetItemCount() == 0)
     96       return;
     97 
     98     gfx::Point screen_point(params.x, params.y);
     99 
    100     // Convert from target window coordinates to root window coordinates.
    101     aura::Window* target_window = GetActiveNativeView();
    102     aura::Window* root_window = target_window->GetRootWindow();
    103     aura::client::ScreenPositionClient* screen_position_client =
    104         aura::client::GetScreenPositionClient(root_window);
    105     if (screen_position_client) {
    106       screen_position_client->ConvertPointToScreen(target_window,
    107                                                    &screen_point);
    108     }
    109     // Enable recursive tasks on the message loop so we can get updates while
    110     // the context menu is being displayed.
    111     base::MessageLoop::ScopedNestableTaskAllower allow(
    112         base::MessageLoop::current());
    113     context_menu_->RunMenuAt(
    114         top_level_widget, screen_point, params.source_type);
    115   }
    116 
    117   aura::Window* GetActiveNativeView() {
    118     return web_contents_->GetFullscreenRenderWidgetHostView()
    119                ? web_contents_->GetFullscreenRenderWidgetHostView()
    120                      ->GetNativeView()
    121                : web_contents_->GetNativeView();
    122   }
    123 
    124   views::Widget* GetTopLevelWidget() {
    125     return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
    126   }
    127 
    128   views::FocusManager* GetFocusManager() {
    129     views::Widget* toplevel_widget = GetTopLevelWidget();
    130     return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL;
    131   }
    132 
    133   void SetInitialFocus() {
    134     if (web_contents_->FocusLocationBarByDefault()) {
    135       if (web_contents_->GetDelegate())
    136         web_contents_->GetDelegate()->SetFocusToLocationBar(false);
    137     } else {
    138       web_contents_->Focus();
    139     }
    140   }
    141   scoped_ptr<RenderViewContextMenuImpl> context_menu_;
    142   content::WebContents* web_contents_;
    143   DISALLOW_COPY_AND_ASSIGN(WebContentsViewDelegateImpl);
    144 };
    145 
    146 }  // namespace
    147 
    148 content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
    149     content::WebContents* web_contents) {
    150   return new WebContentsViewDelegateImpl(web_contents);
    151 }
    152 
    153 }  // namespace athena
    154