1 // Copyright 2014 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/chromeos/login/ui/simple_web_view_dialog.h"
8 #include "ash/shell_window_ids.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/chromeos/login/helper.h"
13 #include "chrome/browser/chromeos/login/ui/captive_portal_window_proxy.h"
14 #include "chrome/browser/command_updater.h"
15 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ssl/security_state_model.h"
18 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
21 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h"
22 #include "chrome/browser/ui/view_ids.h"
23 #include "chrome/browser/ui/views/toolbar/reload_button.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "chrome/grit/theme_resources.h"
26 #include "components/password_manager/core/browser/password_manager.h"
27 #include "content/public/browser/navigation_controller.h"
28 #include "content/public/browser/navigation_entry.h"
29 #include "content/public/browser/web_contents.h"
30 #include "ipc/ipc_message.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/theme_provider.h"
33 #include "ui/views/background.h"
34 #include "ui/views/controls/webview/webview.h"
35 #include "ui/views/layout/grid_layout.h"
36 #include "ui/views/layout/layout_constants.h"
37 #include "ui/views/view.h"
38 #include "ui/views/widget/widget.h"
40 using content::WebContents
;
41 using views::GridLayout
;
45 const int kLocationBarHeight
= 35;
47 // Margin between screen edge and SimpleWebViewDialog border.
48 const int kExternalMargin
= 60;
50 // Margin between WebView and SimpleWebViewDialog border.
51 const int kInnerMargin
= 2;
53 const SkColor kDialogColor
= SK_ColorWHITE
;
55 class ToolbarRowView
: public views::View
{
58 set_background(views::Background::CreateSolidBackground(kDialogColor
));
61 ~ToolbarRowView() override
{}
63 void Init(views::View
* back
,
66 views::View
* location_bar
) {
67 GridLayout
* layout
= new GridLayout(this);
68 SetLayoutManager(layout
);
71 views::ColumnSet
* column_set
= layout
->AddColumnSet(0);
72 column_set
->AddColumn(GridLayout::CENTER
, GridLayout::CENTER
, 0,
73 GridLayout::USE_PREF
, 0, 0);
74 column_set
->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing
);
76 column_set
->AddColumn(GridLayout::CENTER
, GridLayout::CENTER
, 0,
77 GridLayout::USE_PREF
, 0, 0);
78 column_set
->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing
);
80 column_set
->AddColumn(GridLayout::CENTER
, GridLayout::CENTER
, 0,
81 GridLayout::USE_PREF
, 0, 0);
82 column_set
->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing
);
84 column_set
->AddColumn(GridLayout::FILL
, GridLayout::CENTER
, 1,
85 GridLayout::FIXED
, kLocationBarHeight
, 0);
86 column_set
->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing
);
88 layout
->StartRow(0, 0);
89 layout
->AddView(back
);
90 layout
->AddView(forward
);
91 layout
->AddView(reload
);
92 layout
->AddView(location_bar
);
96 DISALLOW_COPY_AND_ASSIGN(ToolbarRowView
);
103 // Stub implementation of ContentSettingBubbleModelDelegate.
104 class StubBubbleModelDelegate
: public ContentSettingBubbleModelDelegate
{
106 StubBubbleModelDelegate() {}
107 ~StubBubbleModelDelegate() override
{}
109 // ContentSettingBubbleModelDelegate implementation:
110 void ShowCollectedCookiesDialog(content::WebContents
* web_contents
) override
{
113 void ShowContentSettingsPage(ContentSettingsType type
) override
{}
115 void ShowLearnMorePage(ContentSettingsType type
) override
{}
118 DISALLOW_COPY_AND_ASSIGN(StubBubbleModelDelegate
);
121 // SimpleWebViewDialog class ---------------------------------------------------
123 SimpleWebViewDialog::SimpleWebViewDialog(Profile
* profile
)
130 bubble_model_delegate_(new StubBubbleModelDelegate
) {
131 command_updater_
.reset(new CommandUpdater(this));
132 command_updater_
->UpdateCommandEnabled(IDC_BACK
, true);
133 command_updater_
->UpdateCommandEnabled(IDC_FORWARD
, true);
134 command_updater_
->UpdateCommandEnabled(IDC_STOP
, true);
135 command_updater_
->UpdateCommandEnabled(IDC_RELOAD
, true);
136 command_updater_
->UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE
, true);
137 command_updater_
->UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE
, true);
140 SimpleWebViewDialog::~SimpleWebViewDialog() {
141 if (web_view_
&& web_view_
->web_contents())
142 web_view_
->web_contents()->SetDelegate(NULL
);
145 void SimpleWebViewDialog::StartLoad(const GURL
& url
) {
146 if (!web_view_container_
.get())
147 web_view_container_
.reset(new views::WebView(profile_
));
148 web_view_
= web_view_container_
.get();
149 web_view_
->set_owned_by_client();
150 web_view_
->GetWebContents()->SetDelegate(this);
151 web_view_
->LoadInitialURL(url
);
153 WebContents
* web_contents
= web_view_
->GetWebContents();
154 DCHECK(web_contents
);
156 // Create the password manager that is needed for the proxy.
157 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
159 autofill::ChromeAutofillClient::FromWebContents(web_contents
));
162 void SimpleWebViewDialog::Init() {
163 // Create the security state model that the toolbar model needs.
164 if (web_view_
->GetWebContents())
165 SecurityStateModel::CreateForWebContents(web_view_
->GetWebContents());
166 toolbar_model_
.reset(new ToolbarModelImpl(this));
168 set_background(views::Background::CreateSolidBackground(kDialogColor
));
170 // Back/Forward buttons.
171 back_
= new views::ImageButton(this);
172 back_
->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON
|
173 ui::EF_MIDDLE_MOUSE_BUTTON
);
174 back_
->set_tag(IDC_BACK
);
175 back_
->SetImageAlignment(views::ImageButton::ALIGN_RIGHT
,
176 views::ImageButton::ALIGN_TOP
);
177 back_
->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK
));
178 back_
->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK
));
179 back_
->set_id(VIEW_ID_BACK_BUTTON
);
181 forward_
= new views::ImageButton(this);
182 forward_
->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON
|
183 ui::EF_MIDDLE_MOUSE_BUTTON
);
184 forward_
->set_tag(IDC_FORWARD
);
185 forward_
->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD
));
186 forward_
->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD
));
187 forward_
->set_id(VIEW_ID_FORWARD_BUTTON
);
190 location_bar_
= new LocationBarView(NULL
, profile_
, command_updater_
.get(),
194 reload_
= new ReloadButton(command_updater_
.get());
195 reload_
->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON
|
196 ui::EF_MIDDLE_MOUSE_BUTTON
);
197 reload_
->set_tag(IDC_RELOAD
);
198 reload_
->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_RELOAD
));
199 reload_
->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD
));
200 reload_
->set_id(VIEW_ID_RELOAD_BUTTON
);
202 // Use separate view to setup custom background.
203 ToolbarRowView
* toolbar_row
= new ToolbarRowView
;
204 toolbar_row
->Init(back_
, forward_
, reload_
, location_bar_
);
207 GridLayout
* layout
= new GridLayout(this);
208 SetLayoutManager(layout
);
210 views::ColumnSet
* column_set
= layout
->AddColumnSet(0);
211 column_set
->AddColumn(GridLayout::FILL
, GridLayout::FILL
, 1,
212 GridLayout::FIXED
, 0, 0);
214 column_set
= layout
->AddColumnSet(1);
215 column_set
->AddPaddingColumn(0, kInnerMargin
);
216 column_set
->AddColumn(GridLayout::FILL
, GridLayout::FILL
, 1,
217 GridLayout::FIXED
, 0, 0);
218 column_set
->AddPaddingColumn(0, kInnerMargin
);
220 // Setup layout rows.
221 layout
->StartRow(0, 0);
222 layout
->AddView(toolbar_row
);
224 layout
->AddPaddingRow(0, kInnerMargin
);
226 layout
->StartRow(1, 1);
227 layout
->AddView(web_view_container_
.get());
228 layout
->AddPaddingRow(0, kInnerMargin
);
232 location_bar_
->Init();
233 UpdateReload(web_view_
->web_contents()->IsLoading(), true);
235 gfx::Rect
bounds(CalculateScreenBounds(gfx::Size()));
236 bounds
.Inset(kExternalMargin
, kExternalMargin
);
237 layout
->set_minimum_size(bounds
.size());
242 void SimpleWebViewDialog::Layout() {
243 views::WidgetDelegateView::Layout();
246 views::View
* SimpleWebViewDialog::GetContentsView() {
250 views::View
* SimpleWebViewDialog::GetInitiallyFocusedView() {
254 void SimpleWebViewDialog::ButtonPressed(views::Button
* sender
,
255 const ui::Event
& event
) {
256 command_updater_
->ExecuteCommand(sender
->tag());
259 content::WebContents
* SimpleWebViewDialog::OpenURL(
260 const content::OpenURLParams
& params
) {
261 // As there are no Browsers right now, this could not actually ever work.
266 void SimpleWebViewDialog::NavigationStateChanged(
268 content::InvalidateTypes changed_flags
) {
270 location_bar_
->Update(NULL
);
275 void SimpleWebViewDialog::LoadingStateChanged(WebContents
* source
,
276 bool to_different_document
) {
277 bool is_loading
= source
->IsLoading();
278 UpdateReload(is_loading
&& to_different_document
, false);
279 command_updater_
->UpdateCommandEnabled(IDC_STOP
, is_loading
);
282 WebContents
* SimpleWebViewDialog::GetWebContents() {
286 ToolbarModel
* SimpleWebViewDialog::GetToolbarModel() {
287 return toolbar_model_
.get();
290 const ToolbarModel
* SimpleWebViewDialog::GetToolbarModel() const {
291 return toolbar_model_
.get();
294 views::Widget
* SimpleWebViewDialog::CreateViewsBubble(
295 views::BubbleDelegateView
* bubble_delegate
) {
296 return views::BubbleDelegateView::CreateBubble(bubble_delegate
);
299 ContentSettingBubbleModelDelegate
*
300 SimpleWebViewDialog::GetContentSettingBubbleModelDelegate() {
301 return bubble_model_delegate_
.get();
304 void SimpleWebViewDialog::ShowWebsiteSettings(
305 content::WebContents
* web_contents
,
307 const SecurityStateModel::SecurityInfo
& security_info
) {
309 // TODO (markusheintz@): implement this
312 PageActionImageView
* SimpleWebViewDialog::CreatePageActionImageView(
313 LocationBarView
* owner
,
314 ExtensionAction
* action
) {
315 // Notreached because SimpleWebViewDialog uses a popup-mode LocationBarView,
316 // and it doesn't create PageActionImageViews.
321 content::WebContents
* SimpleWebViewDialog::GetActiveWebContents() const {
322 return web_view_
->web_contents();
325 void SimpleWebViewDialog::ExecuteCommandWithDisposition(
327 WindowOpenDisposition
) {
328 WebContents
* web_contents
= web_view_
->web_contents();
331 if (web_contents
->GetController().CanGoBack()) {
332 location_bar_
->Revert();
333 web_contents
->GetController().GoBack();
337 if (web_contents
->GetController().CanGoForward()) {
338 location_bar_
->Revert();
339 web_contents
->GetController().GoForward();
343 web_contents
->Stop();
346 // Always reload ignoring cache.
347 case IDC_RELOAD_IGNORING_CACHE
:
348 case IDC_RELOAD_CLEARING_CACHE
:
349 location_bar_
->Revert();
350 web_contents
->GetController().ReloadIgnoringCache(true);
357 void SimpleWebViewDialog::LoadImages() {
358 ui::ThemeProvider
* tp
= GetThemeProvider();
360 back_
->SetImage(views::CustomButton::STATE_NORMAL
,
361 tp
->GetImageSkiaNamed(IDR_BACK
));
362 back_
->SetImage(views::CustomButton::STATE_HOVERED
,
363 tp
->GetImageSkiaNamed(IDR_BACK_H
));
364 back_
->SetImage(views::CustomButton::STATE_PRESSED
,
365 tp
->GetImageSkiaNamed(IDR_BACK_P
));
366 back_
->SetImage(views::CustomButton::STATE_DISABLED
,
367 tp
->GetImageSkiaNamed(IDR_BACK_D
));
369 forward_
->SetImage(views::CustomButton::STATE_NORMAL
,
370 tp
->GetImageSkiaNamed(IDR_FORWARD
));
371 forward_
->SetImage(views::CustomButton::STATE_HOVERED
,
372 tp
->GetImageSkiaNamed(IDR_FORWARD_H
));
373 forward_
->SetImage(views::CustomButton::STATE_PRESSED
,
374 tp
->GetImageSkiaNamed(IDR_FORWARD_P
));
375 forward_
->SetImage(views::CustomButton::STATE_DISABLED
,
376 tp
->GetImageSkiaNamed(IDR_FORWARD_D
));
378 reload_
->LoadImages();
381 void SimpleWebViewDialog::UpdateButtons() {
382 const content::NavigationController
& navigation_controller
=
383 web_view_
->web_contents()->GetController();
384 back_
->SetEnabled(navigation_controller
.CanGoBack());
385 forward_
->SetEnabled(navigation_controller
.CanGoForward());
388 void SimpleWebViewDialog::UpdateReload(bool is_loading
, bool force
) {
391 is_loading
? ReloadButton::MODE_STOP
: ReloadButton::MODE_RELOAD
,
396 } // namespace chromeos