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