This source file includes following definitions.
- allow_accelerators_
- GetWebContents
- SetWebContents
- SetEmbedFullscreenWidgetMode
- LoadInitialURL
- SetFastResize
- OnWebContentsFocused
- SetPreferredSize
- GetClassName
- OnBoundsChanged
- ViewHierarchyChanged
- SkipDefaultKeyEventProcessing
- IsFocusable
- OnFocus
- AboutToRequestFocusFromTabTraversal
- GetAccessibleState
- GetNativeViewAccessible
- GetPreferredSize
- WebContentsFocused
- EmbedsFullscreenWidget
- RenderViewHostChanged
- DidShowFullscreenWidget
- DidDestroyFullscreenWidget
- DidToggleFullscreenModeForTab
- AttachWebContents
- DetachWebContents
- ReattachForFullscreenChange
- CreateWebContents
#include "ui/views/controls/webview/webview.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "ipc/ipc_message.h"
#include "ui/accessibility/ax_enums.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/events/event.h"
#include "ui/views/accessibility/native_view_accessibility.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/views_delegate.h"
namespace views {
const char WebView::kViewClassName[] = "WebView";
WebView::WebView(content::BrowserContext* browser_context)
: holder_(new NativeViewHost()),
embed_fullscreen_widget_mode_enabled_(false),
is_embedding_fullscreen_widget_(false),
browser_context_(browser_context),
allow_accelerators_(false) {
AddChildView(holder_);
NativeViewAccessibility::RegisterWebView(this);
}
WebView::~WebView() {
SetWebContents(NULL);
NativeViewAccessibility::UnregisterWebView(this);
}
content::WebContents* WebView::GetWebContents() {
if (!web_contents()) {
wc_owner_.reset(CreateWebContents(browser_context_));
wc_owner_->SetDelegate(this);
SetWebContents(wc_owner_.get());
}
return web_contents();
}
void WebView::SetWebContents(content::WebContents* replacement) {
if (replacement == web_contents())
return;
DetachWebContents();
WebContentsObserver::Observe(replacement);
if (wc_owner_ != replacement)
wc_owner_.reset();
if (embed_fullscreen_widget_mode_enabled_) {
is_embedding_fullscreen_widget_ =
web_contents() && web_contents()->GetFullscreenRenderWidgetHostView();
} else {
DCHECK(!is_embedding_fullscreen_widget_);
}
AttachWebContents();
}
void WebView::SetEmbedFullscreenWidgetMode(bool enable) {
DCHECK(!web_contents())
<< "Cannot change mode while a WebContents is attached.";
embed_fullscreen_widget_mode_enabled_ = enable;
}
void WebView::LoadInitialURL(const GURL& url) {
GetWebContents()->GetController().LoadURL(
url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL,
std::string());
}
void WebView::SetFastResize(bool fast_resize) {
holder_->set_fast_resize(fast_resize);
}
void WebView::OnWebContentsFocused(content::WebContents* web_contents) {
FocusManager* focus_manager = GetFocusManager();
if (focus_manager)
focus_manager->SetFocusedView(this);
}
void WebView::SetPreferredSize(const gfx::Size& preferred_size) {
preferred_size_ = preferred_size;
PreferredSizeChanged();
}
const char* WebView::GetClassName() const {
return kViewClassName;
}
void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
gfx::Rect holder_bounds(bounds().size());
if (!embed_fullscreen_widget_mode_enabled_ ||
!web_contents() ||
web_contents()->GetCapturerCount() == 0 ||
web_contents()->GetPreferredSize().IsEmpty() ||
!(is_embedding_fullscreen_widget_ ||
(web_contents()->GetDelegate() &&
web_contents()->GetDelegate()->
IsFullscreenForTabOrPending(web_contents())))) {
holder_->SetBoundsRect(holder_bounds);
return;
}
const gfx::Size capture_size = web_contents()->GetPreferredSize();
if (capture_size.width() <= holder_bounds.width() &&
capture_size.height() <= holder_bounds.height()) {
holder_bounds.ClampToCenteredSize(capture_size);
} else {
const int64 x = static_cast<int64>(capture_size.width()) *
holder_bounds.height();
const int64 y = static_cast<int64>(capture_size.height()) *
holder_bounds.width();
if (y < x) {
holder_bounds.ClampToCenteredSize(gfx::Size(
holder_bounds.width(), static_cast<int>(y / capture_size.width())));
} else {
holder_bounds.ClampToCenteredSize(gfx::Size(
static_cast<int>(x / capture_size.height()), holder_bounds.height()));
}
}
holder_->SetBoundsRect(holder_bounds);
}
void WebView::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (details.is_add)
AttachWebContents();
}
bool WebView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
if (allow_accelerators_)
return FocusManager::IsTabTraversalKeyEvent(event);
return web_contents() && !web_contents()->IsCrashed();
}
bool WebView::IsFocusable() const {
return !!web_contents();
}
void WebView::OnFocus() {
if (!web_contents())
return;
if (is_embedding_fullscreen_widget_) {
content::RenderWidgetHostView* const current_fs_view =
web_contents()->GetFullscreenRenderWidgetHostView();
if (current_fs_view)
current_fs_view->Focus();
} else {
web_contents()->GetView()->Focus();
}
}
void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
if (web_contents())
web_contents()->FocusThroughTabTraversal(reverse);
}
void WebView::GetAccessibleState(ui::AXViewState* state) {
state->role = ui::AX_ROLE_GROUP;
}
gfx::NativeViewAccessible WebView::GetNativeViewAccessible() {
if (web_contents()) {
content::RenderWidgetHostView* host_view =
web_contents()->GetRenderWidgetHostView();
if (host_view)
return host_view->GetNativeViewAccessible();
}
return View::GetNativeViewAccessible();
}
gfx::Size WebView::GetPreferredSize() {
if (preferred_size_ == gfx::Size())
return View::GetPreferredSize();
else
return preferred_size_;
}
void WebView::WebContentsFocused(content::WebContents* web_contents) {
DCHECK(wc_owner_.get());
OnWebContentsFocused(wc_owner_.get());
}
bool WebView::EmbedsFullscreenWidget() const {
DCHECK(wc_owner_.get());
return embed_fullscreen_widget_mode_enabled_;
}
void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
FocusManager* const focus_manager = GetFocusManager();
if (focus_manager && focus_manager->GetFocusedView() == this)
OnFocus();
}
void WebView::DidShowFullscreenWidget(int routing_id) {
if (embed_fullscreen_widget_mode_enabled_)
ReattachForFullscreenChange(true);
}
void WebView::DidDestroyFullscreenWidget(int routing_id) {
if (embed_fullscreen_widget_mode_enabled_)
ReattachForFullscreenChange(false);
}
void WebView::DidToggleFullscreenModeForTab(bool entered_fullscreen) {
if (embed_fullscreen_widget_mode_enabled_)
ReattachForFullscreenChange(entered_fullscreen);
}
void WebView::AttachWebContents() {
if (!GetWidget() || !web_contents())
return;
const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ?
web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() :
web_contents()->GetView()->GetNativeView();
OnBoundsChanged(bounds());
if (holder_->native_view() == view_to_attach)
return;
holder_->Attach(view_to_attach);
FocusManager* const focus_manager = GetFocusManager();
if (focus_manager && focus_manager->GetFocusedView() == this)
OnFocus();
#if defined(OS_WIN)
if (!is_embedding_fullscreen_widget_) {
web_contents()->SetParentNativeViewAccessible(
parent()->GetNativeViewAccessible());
}
#endif
}
void WebView::DetachWebContents() {
if (web_contents()) {
holder_->Detach();
#if defined(OS_WIN)
if (!is_embedding_fullscreen_widget_)
web_contents()->SetParentNativeViewAccessible(NULL);
#endif
}
}
void WebView::ReattachForFullscreenChange(bool enter_fullscreen) {
DCHECK(embed_fullscreen_widget_mode_enabled_);
const bool web_contents_has_separate_fs_widget =
web_contents() && web_contents()->GetFullscreenRenderWidgetHostView();
if (is_embedding_fullscreen_widget_ || web_contents_has_separate_fs_widget) {
DetachWebContents();
is_embedding_fullscreen_widget_ =
enter_fullscreen && web_contents_has_separate_fs_widget;
AttachWebContents();
} else {
OnBoundsChanged(bounds());
}
}
content::WebContents* WebView::CreateWebContents(
content::BrowserContext* browser_context) {
content::WebContents* contents = NULL;
if (ViewsDelegate::views_delegate) {
contents = ViewsDelegate::views_delegate->CreateWebContents(
browser_context, NULL);
}
if (!contents) {
content::WebContents::CreateParams create_params(
browser_context, NULL);
return content::WebContents::Create(create_params);
}
return contents;
}
}