16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "athena/content/public/web_contents_view_delegate_creator.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "athena/content/render_view_context_menu_impl.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/web_modal/popup_manager.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/web_modal/single_web_contents_dialog_manager.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/web_modal/web_contents_modal_dialog_host.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/web_modal/web_contents_modal_dialog_manager.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/web_contents.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/web_contents_view_delegate.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/aura/window.h"
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/views/widget/widget.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace athena {
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class WebContentsViewDelegateImpl : public content::WebContentsViewDelegate {
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public:
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit WebContentsViewDelegateImpl(content::WebContents* web_contents)
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : web_contents_(web_contents) {}
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~WebContentsViewDelegateImpl() {}
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE {
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // TODO(oshima): crbug.com/401610
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return NULL;
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual bool Focus() OVERRIDE {
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    web_modal::PopupManager* popup_manager =
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        web_modal::PopupManager::FromWebContents(web_contents_);
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (popup_manager)
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      popup_manager->WasFocused(web_contents_);
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return false;
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void ShowContextMenu(
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      content::RenderFrameHost* render_frame_host,
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const content::ContextMenuParams& params) OVERRIDE {
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ShowMenu(BuildMenu(
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        content::WebContents::FromRenderFrameHost(render_frame_host), params));
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void SizeChanged(const gfx::Size& size) OVERRIDE {
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // TODO(oshima|sadrul): Implement this when sad_tab is componentized.
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // See c/b/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void ShowDisambiguationPopup(
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const gfx::Rect& target_rect,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const SkBitmap& zoomed_bitmap,
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const gfx::NativeView content,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const base::Callback<void(ui::MouseEvent*)>& mouse_cb) OVERRIDE {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void HideDisambiguationPopup() OVERRIDE {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<RenderViewContextMenuImpl> BuildMenu(
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      content::WebContents* web_contents,
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const content::ContextMenuParams& params) {
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<RenderViewContextMenuImpl> menu;
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // If the frame tree does not have a focused frame at this point, do not
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // bother creating RenderViewContextMenuViews.
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // This happens if the frame has navigated to a different page before
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // ContextMenu message was received by the current RenderFrameHost.
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (focused_frame) {
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      menu.reset(new RenderViewContextMenuImpl(focused_frame, params));
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      menu->Init();
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return menu.Pass();
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void ShowMenu(scoped_ptr<RenderViewContextMenuImpl> menu) {
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    context_menu_.reset(menu.release());
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!context_menu_.get())
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return;
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Menus need a Widget to work. If we're not the active tab we won't
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // necessarily be in a widget.
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    views::Widget* top_level_widget = GetTopLevelWidget();
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!top_level_widget)
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return;
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const content::ContextMenuParams& params = context_menu_->params();
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Don't show empty menus.
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (context_menu_->menu_model().GetItemCount() == 0)
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return;
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    gfx::Point screen_point(params.x, params.y);
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Convert from target window coordinates to root window coordinates.
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    aura::Window* target_window = GetActiveNativeView();
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    aura::Window* root_window = target_window->GetRootWindow();
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    aura::client::ScreenPositionClient* screen_position_client =
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        aura::client::GetScreenPositionClient(root_window);
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (screen_position_client) {
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      screen_position_client->ConvertPointToScreen(target_window,
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                   &screen_point);
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Enable recursive tasks on the message loop so we can get updates while
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // the context menu is being displayed.
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        base::MessageLoop::current());
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    context_menu_->RunMenuAt(
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        top_level_widget, screen_point, params.source_type);
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  aura::Window* GetActiveNativeView() {
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return web_contents_->GetFullscreenRenderWidgetHostView()
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)               ? web_contents_->GetFullscreenRenderWidgetHostView()
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                     ->GetNativeView()
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)               : web_contents_->GetNativeView();
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  views::Widget* GetTopLevelWidget() {
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  views::FocusManager* GetFocusManager() {
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    views::Widget* toplevel_widget = GetTopLevelWidget();
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL;
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void SetInitialFocus() {
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (web_contents_->FocusLocationBarByDefault()) {
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (web_contents_->GetDelegate())
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        web_contents_->GetDelegate()->SetFocusToLocationBar(false);
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else {
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      web_contents_->Focus();
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<RenderViewContextMenuImpl> context_menu_;
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::WebContents* web_contents_;
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebContentsViewDelegateImpl);
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)};
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    content::WebContents* web_contents) {
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return new WebContentsViewDelegateImpl(web_contents);
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace athena
154