1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_VIEWS_CONTROLS_WEBVIEW_WEBVIEW_H_
6#define UI_VIEWS_CONTROLS_WEBVIEW_WEBVIEW_H_
7
8#include "base/basictypes.h"
9#include "base/memory/scoped_ptr.h"
10#include "content/public/browser/web_contents_delegate.h"
11#include "content/public/browser/web_contents_observer.h"
12#include "ui/views/accessibility/native_view_accessibility.h"
13#include "ui/views/controls/webview/webview_export.h"
14#include "ui/views/view.h"
15
16namespace views {
17
18class NativeViewHost;
19
20// Provides a view of a WebContents instance.  WebView can be used standalone,
21// creating and displaying an internally-owned WebContents; or within a full
22// browser where the browser swaps its own WebContents instances in/out (e.g.,
23// for browser tabs).
24//
25// WebView creates and owns a single child view, a NativeViewHost, which will
26// hold and display the native view provided by a WebContents.
27//
28// EmbedFullscreenWidgetMode: When enabled, WebView will observe for WebContents
29// fullscreen changes and automatically swap the normal native view with the
30// fullscreen native view (if different).  In addition, if the WebContents is
31// being screen-captured, the view will be centered within WebView, sized to
32// the aspect ratio of the capture video resolution, and scaling will be avoided
33// whenever possible.
34class WEBVIEW_EXPORT WebView : public View,
35                               public content::WebContentsDelegate,
36                               public content::WebContentsObserver {
37 public:
38  static const char kViewClassName[];
39
40  explicit WebView(content::BrowserContext* browser_context);
41  virtual ~WebView();
42
43  // This creates a WebContents if none is yet associated with this WebView. The
44  // WebView owns this implicitly created WebContents.
45  content::WebContents* GetWebContents();
46
47  // WebView does not assume ownership of WebContents set via this method, only
48  // those it implicitly creates via GetWebContents() above.
49  void SetWebContents(content::WebContents* web_contents);
50
51  // If |mode| is true, WebView will register itself with WebContents as a
52  // WebContentsObserver, monitor for the showing/destruction of fullscreen
53  // render widgets, and alter its child view hierarchy to embed the fullscreen
54  // widget or restore the normal WebContentsView.
55  void SetEmbedFullscreenWidgetMode(bool mode);
56
57  content::BrowserContext* browser_context() { return browser_context_; }
58
59  // Loads the initial URL to display in the attached WebContents. Creates the
60  // WebContents if none is attached yet. Note that this is intended as a
61  // convenience for loading the initial URL, and so URLs are navigated with
62  // PAGE_TRANSITION_AUTO_TOPLEVEL, so this is not intended as a general purpose
63  // navigation method - use WebContents' API directly.
64  void LoadInitialURL(const GURL& url);
65
66  // Controls how the attached WebContents is resized.
67  // false = WebContents' views' bounds are updated continuously as the
68  //         WebView's bounds change (default).
69  // true  = WebContents' views' position is updated continuously but its size
70  //         is not (which may result in some clipping or under-painting) until
71  //         a continuous size operation completes. This allows for smoother
72  //         resizing performance during interactive resizes and animations.
73  void SetFastResize(bool fast_resize);
74
75  // Called when the WebContents is focused.
76  // TODO(beng): This view should become a WebContentsViewObserver when a
77  //             WebContents is attached, and not rely on the delegate to
78  //             forward this notification.
79  void OnWebContentsFocused(content::WebContents* web_contents);
80
81  // When used to host UI, we need to explicitly allow accelerators to be
82  // processed. Default is false.
83  void set_allow_accelerators(bool allow_accelerators) {
84    allow_accelerators_ = allow_accelerators;
85  }
86
87  // Sets the preferred size. If empty, View's implementation of
88  // GetPreferredSize() is used.
89  void SetPreferredSize(const gfx::Size& preferred_size);
90
91  // Overridden from View:
92  virtual const char* GetClassName() const OVERRIDE;
93  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
94
95 protected:
96  // Swaps the owned WebContents |wc_owner_| with |new_web_contents|. Returns
97  // the previously owned WebContents.
98  scoped_ptr<content::WebContents> SwapWebContents(
99      scoped_ptr<content::WebContents> new_web_contents);
100
101  // Overridden from View:
102  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
103  virtual void ViewHierarchyChanged(
104      const ViewHierarchyChangedDetails& details) OVERRIDE;
105  virtual bool SkipDefaultKeyEventProcessing(
106      const ui::KeyEvent& event) OVERRIDE;
107  virtual void OnFocus() OVERRIDE;
108  virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE;
109  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
110  virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
111  virtual gfx::Size GetPreferredSize() const OVERRIDE;
112
113  // Overridden from content::WebContentsDelegate:
114  virtual void WebContentsFocused(content::WebContents* web_contents) OVERRIDE;
115  virtual bool EmbedsFullscreenWidget() const OVERRIDE;
116
117  // Overridden from content::WebContentsObserver:
118  virtual void RenderViewDeleted(
119      content::RenderViewHost* render_view_host) OVERRIDE;
120  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
121  virtual void RenderViewHostChanged(
122      content::RenderViewHost* old_host,
123      content::RenderViewHost* new_host) OVERRIDE;
124  virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE;
125  virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE;
126  virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) OVERRIDE;
127  virtual void DidAttachInterstitialPage() OVERRIDE;
128  virtual void DidDetachInterstitialPage() OVERRIDE;
129  // Workaround for MSVC++ linker bug/feature that requires
130  // instantiation of the inline IPC::Listener methods in all translation units.
131  virtual void OnChannelConnected(int32 peer_id) OVERRIDE {}
132  virtual void OnChannelError() OVERRIDE {}
133  virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE {}
134
135 private:
136  void AttachWebContents();
137  void DetachWebContents();
138  void ReattachForFullscreenChange(bool enter_fullscreen);
139  void NotifyMaybeTextInputClientChanged();
140
141  // Create a regular or test web contents (based on whether we're running
142  // in a unit test or not).
143  content::WebContents* CreateWebContents(
144      content::BrowserContext* browser_context);
145
146  NativeViewHost* const holder_;
147  // Non-NULL if |web_contents()| was created and is owned by this WebView.
148  scoped_ptr<content::WebContents> wc_owner_;
149  // When true, WebView auto-embeds fullscreen widgets as a child view.
150  bool embed_fullscreen_widget_mode_enabled_;
151  // Set to true while WebView is embedding a fullscreen widget view as a child
152  // view instead of the normal WebContentsView render view. Note: This will be
153  // false in the case of non-Flash fullscreen.
154  bool is_embedding_fullscreen_widget_;
155  content::BrowserContext* browser_context_;
156  bool allow_accelerators_;
157  gfx::Size preferred_size_;
158
159  DISALLOW_COPY_AND_ASSIGN(WebView);
160};
161
162}  // namespace views
163
164#endif  // UI_VIEWS_CONTROLS_WEBVIEW_WEBVIEW_H_
165