// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/views/extensions/extension_view_views.h" #include #include "chrome/browser/extensions/extension_view_host.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/extensions/extension_popup.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_host.h" #include "extensions/common/view_type.h" #include "ui/events/event.h" #include "ui/views/controls/native/native_view_host.h" #include "ui/views/widget/widget.h" #if defined(USE_AURA) #include "ui/base/cursor/cursor.h" #endif ExtensionViewViews::ExtensionViewViews(extensions::ExtensionHost* host, Browser* browser) : views::WebView(browser ? browser->profile() : nullptr), host_(host), browser_(browser), container_(nullptr) { SetWebContents(host_->web_contents()); } ExtensionViewViews::~ExtensionViewViews() { if (parent()) parent()->RemoveChildView(this); } Browser* ExtensionViewViews::GetBrowser() { return browser_; } void ExtensionViewViews::SetVisible(bool is_visible) { if (is_visible != visible()) { views::WebView::SetVisible(is_visible); // Also tell RenderWidgetHostView the new visibility. Despite its name, it // is not part of the View hierarchy and does not know about the change // unless we tell it. content::RenderWidgetHostView* host_view = host_->render_view_host()->GetWidget()->GetView(); if (host_view) { if (is_visible) host_view->Show(); else host_view->Hide(); } } } gfx::NativeView ExtensionViewViews::GetNativeView() { return holder()->native_view(); } void ExtensionViewViews::ResizeDueToAutoResize( content::WebContents* web_contents, const gfx::Size& new_size) { // Don't actually do anything with this information until we have been shown. // Size changes will not be honored by lower layers while we are hidden. if (!visible()) { pending_preferred_size_ = new_size; return; } if (new_size != GetPreferredSize()) SetPreferredSize(new_size); } void ExtensionViewViews::RenderViewCreated( content::RenderViewHost* render_view_host) { extensions::ViewType host_type = host_->extension_host_type(); if (host_type == extensions::VIEW_TYPE_EXTENSION_POPUP) { host_->render_view_host()->EnableAutoResize( gfx::Size(ExtensionPopup::kMinWidth, ExtensionPopup::kMinHeight), gfx::Size(ExtensionPopup::kMaxWidth, ExtensionPopup::kMaxHeight)); } } void ExtensionViewViews::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { if (browser_) { // Handle lower priority browser shortcuts such as Ctrl-f. browser_->HandleKeyboardEvent(source, event); return; } unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, GetFocusManager()); } void ExtensionViewViews::DidStopLoading() { // We wait to show the ExtensionViewViews until it has loaded, and the view // has actually been created. These can happen in different orders. // TODO(devlin): Can they? Isn't the view created during construction? if (!visible() && host_->has_loaded_once()) { SetVisible(true); ResizeDueToAutoResize(web_contents(), pending_preferred_size_); } } gfx::NativeCursor ExtensionViewViews::GetCursor(const ui::MouseEvent& event) { return gfx::kNullCursor; } gfx::Size ExtensionViewViews::GetMinimumSize() const { // If the minimum size has never been set, returns the preferred size (same // behavior as views::View). return (minimum_size_ == gfx::Size()) ? GetPreferredSize() : minimum_size_; } void ExtensionViewViews::PreferredSizeChanged() { View::PreferredSizeChanged(); if (container_) container_->OnExtensionSizeChanged(this); } void ExtensionViewViews::OnWebContentsAttached() { host_->CreateRenderViewSoon(); SetVisible(false); } namespace extensions { // static scoped_ptr ExtensionViewHost::CreateExtensionView( ExtensionViewHost* host, Browser* browser) { scoped_ptr view(new ExtensionViewViews(host, browser)); // We own |view_|, so don't auto delete when it's removed from the view // hierarchy. view->set_owned_by_client(); return std::move(view); } } // namespace extensions