web_contents_view_delegate_factory_impl.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file.
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "athena/content/public/web_contents_view_delegate_creator.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "athena/content/render_view_context_menu_impl.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "components/web_modal/popup_manager.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "components/web_modal/single_web_contents_dialog_manager.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "components/web_modal/web_contents_modal_dialog_host.h"
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "components/web_modal/web_contents_modal_dialog_manager.h"
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/browser/render_widget_host_view.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/web_contents.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/browser/web_contents_delegate.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/web_contents_view_delegate.h"
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/aura/client/screen_position_client.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/aura/window.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/widget/widget.h"
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace athena {
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebContentsViewDelegateImpl : public content::WebContentsViewDelegate {
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit WebContentsViewDelegateImpl(content::WebContents* web_contents)
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : web_contents_(web_contents) {}
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~WebContentsViewDelegateImpl() {}
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE {
30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // TODO(oshima): crbug.com/401610
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return NULL;
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual bool Focus() OVERRIDE {
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    web_modal::PopupManager* popup_manager =
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        web_modal::PopupManager::FromWebContents(web_contents_);
37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (popup_manager)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      popup_manager->WasFocused(web_contents_);
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void TakeFocus(bool reverse) OVERRIDE {}
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void StoreFocus() OVERRIDE {}
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void RestoreFocus() OVERRIDE {}
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void ShowContextMenu(
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      content::RenderFrameHost* render_frame_host,
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const content::ContextMenuParams& params) OVERRIDE {
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ShowMenu(BuildMenu(
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        content::WebContents::FromRenderFrameHost(render_frame_host), params));
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SizeChanged(const gfx::Size& size) OVERRIDE {
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // TODO(oshima|sadrul): Implement this when sad_tab is componentized.
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // See c/b/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<RenderViewContextMenuImpl> BuildMenu(
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      content::WebContents* web_contents,
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const content::ContextMenuParams& params) {
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    scoped_ptr<RenderViewContextMenuImpl> menu;
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // If the frame tree does not have a focused frame at this point, do not
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // bother creating RenderViewContextMenuViews.
65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // This happens if the frame has navigated to a different page before
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // ContextMenu message was received by the current RenderFrameHost.
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (focused_frame) {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      menu.reset(new RenderViewContextMenuImpl(focused_frame, params));
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      menu->Init();
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return menu.Pass();
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ShowMenu(scoped_ptr<RenderViewContextMenuImpl> menu) {
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_menu_.reset(menu.release());
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (!context_menu_.get())
78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return;
79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Menus need a Widget to work. If we're not the active tab we won't
81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // necessarily be in a widget.
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    views::Widget* top_level_widget = GetTopLevelWidget();
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!top_level_widget)
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::ContextMenuParams& params = context_menu_->params();
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Don't show empty menus.
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (context_menu_->menu_model().GetItemCount() == 0)
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Point screen_point(params.x, params.y);
92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Convert from target window coordinates to root window coordinates.
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    aura::Window* target_window = GetActiveNativeView();
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    aura::Window* root_window = target_window->GetRootWindow();
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    aura::client::ScreenPositionClient* screen_position_client =
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        aura::client::GetScreenPositionClient(root_window);
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (screen_position_client) {
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      screen_position_client->ConvertPointToScreen(target_window,
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                   &screen_point);
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Enable recursive tasks on the message loop so we can get updates while
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // the context menu is being displayed.
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::MessageLoop::current());
106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    context_menu_->RunMenuAt(
107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        top_level_widget, screen_point, params.source_type);
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* GetActiveNativeView() {
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return web_contents_->GetFullscreenRenderWidgetHostView()
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               ? web_contents_->GetFullscreenRenderWidgetHostView()
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                     ->GetNativeView()
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)               : web_contents_->GetNativeView();
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* GetTopLevelWidget() {
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::FocusManager* GetFocusManager() {
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    views::Widget* toplevel_widget = GetTopLevelWidget();
123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL;
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SetInitialFocus() {
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (web_contents_->FocusLocationBarByDefault()) {
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (web_contents_->GetDelegate())
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        web_contents_->GetDelegate()->SetFocusToLocationBar(false);
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    } else {
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      web_contents_->Focus();
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<RenderViewContextMenuImpl> context_menu_;
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  content::WebContents* web_contents_;
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebContentsViewDelegateImpl);
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    content::WebContents* web_contents) {
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return new WebContentsViewDelegateImpl(web_contents);
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace athena
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace web_modal {
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochSingleWebContentsDialogManager*
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)WebContentsModalDialogManager::CreateNativeWebModalManager(
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NativeWebContentsModalDialog dialog,
153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SingleWebContentsDialogManagerDelegate* native_delegate) {
154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(oshima): Investigate if we need to implement this.
155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  NOTREACHED();
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace web_modal
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)