Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / extension_dialog.cc
blobe4f5f5cc34db97b33ed05ec5a100cf7f4032d973
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.
5 #include "chrome/browser/ui/views/extensions/extension_dialog.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/extension_view_host.h"
9 #include "chrome/browser/extensions/extension_view_host_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/views/constrained_window_views.h"
12 #include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/render_widget_host_view.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_view.h"
19 #include "ui/base/base_window.h"
20 #include "ui/gfx/screen.h"
21 #include "ui/views/background.h"
22 #include "ui/views/widget/widget.h"
23 #include "url/gurl.h"
25 using content::BrowserContext;
26 using content::WebContents;
28 ExtensionDialog::ExtensionDialog(extensions::ExtensionViewHost* host,
29 ExtensionDialogObserver* observer)
30 : host_(host),
31 observer_(observer) {
32 AddRef(); // Balanced in DeleteDelegate();
34 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
35 content::Source<BrowserContext>(host->browser_context()));
36 // Listen for the containing view calling window.close();
37 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
38 content::Source<BrowserContext>(host->browser_context()));
39 // Listen for a crash or other termination of the extension process.
40 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
41 content::Source<BrowserContext>(host->browser_context()));
44 ExtensionDialog::~ExtensionDialog() {
47 // static
48 ExtensionDialog* ExtensionDialog::Show(
49 const GURL& url,
50 ui::BaseWindow* base_window,
51 Profile* profile,
52 WebContents* web_contents,
53 int width,
54 int height,
55 int min_width,
56 int min_height,
57 const base::string16& title,
58 ExtensionDialogObserver* observer) {
59 extensions::ExtensionViewHost* host =
60 extensions::ExtensionViewHostFactory::CreateDialogHost(url, profile);
61 if (!host)
62 return NULL;
63 // Preferred size must be set before views::Widget::CreateWindowWithParent
64 // is called because CreateWindowWithParent refers the result of CanResize().
65 host->view()->SetPreferredSize(gfx::Size(width, height));
66 host->view()->set_minimum_size(gfx::Size(min_width, min_height));
67 host->SetAssociatedWebContents(web_contents);
69 CHECK(base_window);
70 ExtensionDialog* dialog = new ExtensionDialog(host, observer);
71 dialog->set_title(title);
72 dialog->InitWindow(base_window, width, height);
74 // Show a white background while the extension loads. This is prettier than
75 // flashing a black unfilled window frame.
76 host->view()->set_background(
77 views::Background::CreateSolidBackground(0xFF, 0xFF, 0xFF));
78 host->view()->SetVisible(true);
80 // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
81 host->host_contents()->GetView()->Focus();
82 return dialog;
85 void ExtensionDialog::InitWindow(ui::BaseWindow* base_window,
86 int width,
87 int height) {
88 gfx::NativeWindow parent = base_window->GetNativeWindow();
89 views::Widget* window = CreateBrowserModalDialogViews(this, parent);
91 // Center the window over the browser.
92 gfx::Point center = base_window->GetBounds().CenterPoint();
93 int x = center.x() - width / 2;
94 int y = center.y() - height / 2;
95 // Ensure the top left and top right of the window are on screen, with
96 // priority given to the top left.
97 gfx::Rect screen_rect = gfx::Screen::GetScreenFor(parent)->
98 GetDisplayNearestPoint(center).bounds();
99 gfx::Rect bounds_rect = gfx::Rect(x, y, width, height);
100 bounds_rect.AdjustToFit(screen_rect);
101 window->SetBounds(bounds_rect);
103 window->Show();
104 // TODO(jamescook): Remove redundant call to Activate()?
105 window->Activate();
108 void ExtensionDialog::ObserverDestroyed() {
109 observer_ = NULL;
112 void ExtensionDialog::MaybeFocusRenderView() {
113 views::FocusManager* focus_manager = GetWidget()->GetFocusManager();
114 DCHECK(focus_manager != NULL);
116 // Already there's a focused view, so no need to switch the focus.
117 if (focus_manager->GetFocusedView())
118 return;
120 content::RenderWidgetHostView* view = host()->render_view_host()->GetView();
121 if (!view)
122 return;
124 view->Focus();
127 /////////////////////////////////////////////////////////////////////////////
128 // views::DialogDelegate overrides.
130 int ExtensionDialog::GetDialogButtons() const {
131 // The only user, SelectFileDialogExtension, provides its own buttons.
132 return ui::DIALOG_BUTTON_NONE;
135 bool ExtensionDialog::CanResize() const {
136 // Can resize only if minimum contents size set.
137 return host_->view()->GetPreferredSize() != gfx::Size();
140 void ExtensionDialog::SetMinimumContentsSize(int width, int height) {
141 host_->view()->SetPreferredSize(gfx::Size(width, height));
144 ui::ModalType ExtensionDialog::GetModalType() const {
145 return ui::MODAL_TYPE_WINDOW;
148 bool ExtensionDialog::ShouldShowWindowTitle() const {
149 return !window_title_.empty();
152 base::string16 ExtensionDialog::GetWindowTitle() const {
153 return window_title_;
156 void ExtensionDialog::WindowClosing() {
157 if (observer_)
158 observer_->ExtensionDialogClosing(this);
161 void ExtensionDialog::DeleteDelegate() {
162 // The window has finished closing. Allow ourself to be deleted.
163 Release();
166 views::Widget* ExtensionDialog::GetWidget() {
167 return host_->view()->GetWidget();
170 const views::Widget* ExtensionDialog::GetWidget() const {
171 return host_->view()->GetWidget();
174 views::View* ExtensionDialog::GetContentsView() {
175 return host_->view();
178 bool ExtensionDialog::UseNewStyleForThisDialog() const {
179 return false;
182 /////////////////////////////////////////////////////////////////////////////
183 // content::NotificationObserver overrides.
185 void ExtensionDialog::Observe(int type,
186 const content::NotificationSource& source,
187 const content::NotificationDetails& details) {
188 switch (type) {
189 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
190 // Avoid potential overdraw by removing the temporary background after
191 // the extension finishes loading.
192 host_->view()->set_background(NULL);
193 // The render view is created during the LoadURL(), so we should
194 // set the focus to the view if nobody else takes the focus.
195 if (content::Details<extensions::ExtensionHost>(host()) == details)
196 MaybeFocusRenderView();
197 break;
198 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
199 // If we aren't the host of the popup, then disregard the notification.
200 if (content::Details<extensions::ExtensionHost>(host()) != details)
201 return;
202 GetWidget()->Close();
203 break;
204 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
205 if (content::Details<extensions::ExtensionHost>(host()) != details)
206 return;
207 if (observer_)
208 observer_->ExtensionTerminated(this);
209 break;
210 default:
211 NOTREACHED() << L"Received unexpected notification";
212 break;