summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views/extensions/extension_view_views.cc
blob: dc94db042e432b3110548531a61cc9e16708400f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// 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 <utility>

#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<ExtensionView> ExtensionViewHost::CreateExtensionView(
    ExtensionViewHost* host,
    Browser* browser) {
  scoped_ptr<ExtensionViewViews> 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