Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: chrome/browser/ui/views/page_info/website_settings_popup_view.cc

Issue 2754383004: Rename WebsiteSettings code to PageInfo. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/ui/views/page_info/website_settings_popup_view.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <vector>
11
12 #include "base/i18n/rtl.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/browser/certificate_viewer.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_dialogs.h"
23 #include "chrome/browser/ui/layout_constants.h"
24 #include "chrome/browser/ui/page_info/website_settings.h"
25 #include "chrome/browser/ui/views/collected_cookies_views.h"
26 #include "chrome/browser/ui/views/harmony/layout_delegate.h"
27 #include "chrome/browser/ui/views/page_info/chosen_object_row.h"
28 #include "chrome/browser/ui/views/page_info/non_accessible_image_view.h"
29 #include "chrome/browser/ui/views/page_info/permission_selector_row.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/grit/chromium_strings.h"
32 #include "chrome/grit/generated_resources.h"
33 #include "chrome/grit/theme_resources.h"
34 #include "components/content_settings/core/common/content_settings_types.h"
35 #include "components/strings/grit/components_chromium_strings.h"
36 #include "components/strings/grit/components_strings.h"
37 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/user_metrics.h"
39 #include "extensions/common/constants.h"
40 #include "ui/base/l10n/l10n_util.h"
41 #include "ui/base/material_design/material_design_controller.h"
42 #include "ui/base/models/simple_menu_model.h"
43 #include "ui/base/resource/resource_bundle.h"
44 #include "ui/gfx/canvas.h"
45 #include "ui/gfx/font_list.h"
46 #include "ui/gfx/geometry/insets.h"
47 #include "ui/gfx/image/image.h"
48 #include "ui/resources/grit/ui_resources.h"
49 #include "ui/views/border.h"
50 #include "ui/views/controls/button/image_button.h"
51 #include "ui/views/controls/button/md_text_button.h"
52 #include "ui/views/controls/image_view.h"
53 #include "ui/views/controls/label.h"
54 #include "ui/views/controls/link.h"
55 #include "ui/views/controls/styled_label.h"
56 #include "ui/views/layout/box_layout.h"
57 #include "ui/views/layout/grid_layout.h"
58 #include "ui/views/layout/layout_manager.h"
59 #include "ui/views/view.h"
60 #include "ui/views/widget/widget.h"
61 #include "url/gurl.h"
62
63 namespace {
64
65 // NOTE(jdonnelly): This use of this process-wide variable assumes that there's
66 // never more than one website settings popup shown and that it's associated
67 // with the current window. If this assumption fails in the future, we'll need
68 // to return a weak pointer from ShowPopup so callers can associate it with the
69 // current window (or other context) and check if the popup they care about is
70 // showing.
71 WebsiteSettingsPopupView::PopupType g_shown_popup_type =
72 WebsiteSettingsPopupView::POPUP_NONE;
73
74 // General constants -----------------------------------------------------------
75
76 // Popup width constraints.
77 const int kMinPopupWidth = 320;
78 const int kMaxPopupWidth = 1000;
79
80 // Security Section (PopupHeaderView) ------------------------------------------
81
82 // Margin and padding values for the |PopupHeaderView|.
83 const int kHeaderMarginBottom = 10;
84 const int kHeaderPaddingBottom = 13;
85
86 // Spacing between labels in the header.
87 const int kHeaderLabelSpacing = 4;
88
89 // Site Settings Section -------------------------------------------------------
90
91 // Spacing above and below the cookies view.
92 const int kCookiesViewVerticalPadding = 6;
93
94 // Spacing between a permission image and the text.
95 const int kPermissionImageSpacing = 6;
96
97 // Spacing between rows in the site settings section
98 const int kPermissionsVerticalSpacing = 12;
99
100 // Spacing between the label and the menu.
101 const int kPermissionMenuSpacing = 16;
102
103 // Button/styled label/link IDs ------------------------------------------------
104 const int BUTTON_CLOSE = 1337;
105 const int STYLED_LABEL_SECURITY_DETAILS = 1338;
106 const int STYLED_LABEL_RESET_CERTIFICATE_DECISIONS = 1339;
107 const int LINK_COOKIE_DIALOG = 1340;
108 const int LINK_SITE_SETTINGS = 1341;
109
110 // The default, ui::kTitleFontSizeDelta, is too large for the website settings
111 // bubble (e.g. +3). Use +1 to obtain a smaller font.
112 constexpr int kSummaryFontSizeDelta = 1;
113
114 // Adds a ColumnSet on |layout| with a single View column and padding columns
115 // on either side of it with |margin| width.
116 void AddColumnWithSideMargin(views::GridLayout* layout, int margin, int id) {
117 views::ColumnSet* column_set = layout->AddColumnSet(id);
118 column_set->AddPaddingColumn(0, margin);
119 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
120 views::GridLayout::USE_PREF, 0, 0);
121 column_set->AddPaddingColumn(0, margin);
122 }
123
124 } // namespace
125
126 // |PopupHeaderView| is the UI element (view) that represents the header of the
127 // |WebsiteSettingsPopupView|. The header shows the status of the site's
128 // identity check and the name of the site's identity.
129 class PopupHeaderView : public views::View {
130 public:
131 PopupHeaderView(views::ButtonListener* button_listener,
132 views::StyledLabelListener* styled_label_listener,
133 int side_margin);
134 ~PopupHeaderView() override;
135
136 // Sets the security summary for the current page.
137 void SetSummary(const base::string16& summary_text);
138
139 // Sets the security details for the current page.
140 void SetDetails(const base::string16& details_text);
141
142 void AddResetDecisionsLabel();
143
144 private:
145 // The listener for the styled labels in this view.
146 views::StyledLabelListener* styled_label_listener_;
147
148 // The label that displays the status of the identity check for this site.
149 // Includes a link to open the Chrome Help Center article about connection
150 // security.
151 views::StyledLabel* details_label_;
152
153 // A container for the styled label with a link for resetting cert decisions.
154 // This is only shown sometimes, so we use a container to keep track of
155 // where to place it (if needed).
156 views::View* reset_decisions_label_container_;
157 views::StyledLabel* reset_decisions_label_;
158
159 DISALLOW_COPY_AND_ASSIGN(PopupHeaderView);
160 };
161
162 // Website Settings are not supported for internal Chrome pages and extension
163 // pages. Instead of the |WebsiteSettingsPopupView|, the
164 // |InternalPageInfoPopupView| is displayed.
165 class InternalPageInfoPopupView : public views::BubbleDialogDelegateView {
166 public:
167 // If |anchor_view| is nullptr, or has no Widget, |parent_window| may be
168 // provided to ensure this bubble is closed when the parent closes.
169 InternalPageInfoPopupView(views::View* anchor_view,
170 gfx::NativeView parent_window,
171 const GURL& url);
172 ~InternalPageInfoPopupView() override;
173
174 // views::BubbleDialogDelegateView:
175 void OnWidgetDestroying(views::Widget* widget) override;
176 int GetDialogButtons() const override;
177
178 private:
179 friend class WebsiteSettingsPopupView;
180
181 // Used around icon and inside bubble border.
182 static constexpr int kSpacing = 12;
183
184 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView);
185 };
186
187 ////////////////////////////////////////////////////////////////////////////////
188 // Popup Header
189 ////////////////////////////////////////////////////////////////////////////////
190
191 PopupHeaderView::PopupHeaderView(
192 views::ButtonListener* button_listener,
193 views::StyledLabelListener* styled_label_listener,
194 int side_margin)
195 : styled_label_listener_(styled_label_listener),
196 details_label_(nullptr),
197 reset_decisions_label_container_(nullptr),
198 reset_decisions_label_(nullptr) {
199 views::GridLayout* layout = new views::GridLayout(this);
200 SetLayoutManager(layout);
201
202 const int label_column_status = 1;
203 AddColumnWithSideMargin(layout, side_margin, label_column_status);
204 layout->AddPaddingRow(0, kHeaderLabelSpacing);
205
206 layout->StartRow(0, label_column_status);
207 details_label_ =
208 new views::StyledLabel(base::string16(), styled_label_listener);
209 details_label_->set_id(STYLED_LABEL_SECURITY_DETAILS);
210 layout->AddView(details_label_, 1, 1, views::GridLayout::FILL,
211 views::GridLayout::LEADING);
212
213 layout->StartRow(0, label_column_status);
214 reset_decisions_label_container_ = new views::View();
215 reset_decisions_label_container_->SetLayoutManager(
216 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
217 layout->AddView(reset_decisions_label_container_, 1, 1,
218 views::GridLayout::FILL, views::GridLayout::LEADING);
219
220 layout->AddPaddingRow(1, kHeaderPaddingBottom);
221 }
222
223 PopupHeaderView::~PopupHeaderView() {}
224
225 void PopupHeaderView::SetDetails(const base::string16& details_text) {
226 std::vector<base::string16> subst;
227 subst.push_back(details_text);
228 subst.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
229
230 std::vector<size_t> offsets;
231
232 base::string16 text = base::ReplaceStringPlaceholders(
233 base::ASCIIToUTF16("$1 $2"), subst, &offsets);
234 details_label_->SetText(text);
235 gfx::Range details_range(offsets[1], text.length());
236
237 views::StyledLabel::RangeStyleInfo link_style =
238 views::StyledLabel::RangeStyleInfo::CreateForLink();
239 if (!ui::MaterialDesignController::IsSecondaryUiMaterial())
240 link_style.font_style |= gfx::Font::FontStyle::UNDERLINE;
241 link_style.disable_line_wrapping = false;
242
243 details_label_->AddStyleRange(details_range, link_style);
244 }
245
246 void PopupHeaderView::AddResetDecisionsLabel() {
247 std::vector<base::string16> subst;
248 subst.push_back(
249 l10n_util::GetStringUTF16(IDS_PAGEINFO_INVALID_CERTIFICATE_DESCRIPTION));
250 subst.push_back(l10n_util::GetStringUTF16(
251 IDS_PAGEINFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON));
252
253 std::vector<size_t> offsets;
254
255 base::string16 text = base::ReplaceStringPlaceholders(
256 base::ASCIIToUTF16("$1 $2"), subst, &offsets);
257 reset_decisions_label_ = new views::StyledLabel(text, styled_label_listener_);
258 reset_decisions_label_->set_id(STYLED_LABEL_RESET_CERTIFICATE_DECISIONS);
259 gfx::Range link_range(offsets[1], text.length());
260
261 views::StyledLabel::RangeStyleInfo link_style =
262 views::StyledLabel::RangeStyleInfo::CreateForLink();
263 if (!ui::MaterialDesignController::IsSecondaryUiMaterial())
264 link_style.font_style |= gfx::Font::FontStyle::UNDERLINE;
265 link_style.disable_line_wrapping = false;
266
267 reset_decisions_label_->AddStyleRange(link_range, link_style);
268 // Fit the styled label to occupy available width.
269 reset_decisions_label_->SizeToFit(0);
270 reset_decisions_label_container_->AddChildView(reset_decisions_label_);
271
272 // Now that it contains a label, the container needs padding at the top.
273 reset_decisions_label_container_->SetBorder(
274 views::CreateEmptyBorder(8, 0, 0, 0));
275
276 InvalidateLayout();
277 }
278
279 ////////////////////////////////////////////////////////////////////////////////
280 // InternalPageInfoPopupView
281 ////////////////////////////////////////////////////////////////////////////////
282
283 InternalPageInfoPopupView::InternalPageInfoPopupView(
284 views::View* anchor_view,
285 gfx::NativeView parent_window,
286 const GURL& url)
287 : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT) {
288 g_shown_popup_type = WebsiteSettingsPopupView::POPUP_INTERNAL_PAGE;
289 set_parent_window(parent_window);
290
291 int text = IDS_PAGE_INFO_INTERNAL_PAGE;
292 int icon = IDR_PRODUCT_LOGO_16;
293 if (url.SchemeIs(extensions::kExtensionScheme)) {
294 text = IDS_PAGE_INFO_EXTENSION_PAGE;
295 icon = IDR_PLUGINS_FAVICON;
296 } else if (url.SchemeIs(content::kViewSourceScheme)) {
297 text = IDS_PAGE_INFO_VIEW_SOURCE_PAGE;
298 // view-source scheme uses the same icon as chrome:// pages.
299 icon = IDR_PRODUCT_LOGO_16;
300 } else if (!url.SchemeIs(content::kChromeUIScheme) &&
301 !url.SchemeIs(content::kChromeDevToolsScheme)) {
302 NOTREACHED();
303 }
304
305 // Compensate for built-in vertical padding in the anchor view's image.
306 set_anchor_view_insets(gfx::Insets(
307 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
308
309 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, kSpacing,
310 kSpacing, kSpacing));
311 set_margins(gfx::Insets());
312 views::ImageView* icon_view = new NonAccessibleImageView();
313 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
314 icon_view->SetImage(rb.GetImageSkiaNamed(icon));
315 AddChildView(icon_view);
316
317 views::Label* label = new views::Label(l10n_util::GetStringUTF16(text));
318 label->SetMultiLine(true);
319 label->SetAllowCharacterBreak(true);
320 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
321 AddChildView(label);
322
323 views::BubbleDialogDelegateView::CreateBubble(this);
324 }
325
326 InternalPageInfoPopupView::~InternalPageInfoPopupView() {}
327
328 void InternalPageInfoPopupView::OnWidgetDestroying(views::Widget* widget) {
329 g_shown_popup_type = WebsiteSettingsPopupView::POPUP_NONE;
330 }
331
332 int InternalPageInfoPopupView::GetDialogButtons() const {
333 return ui::DIALOG_BUTTON_NONE;
334 }
335
336 ////////////////////////////////////////////////////////////////////////////////
337 // WebsiteSettingsPopupView
338 ////////////////////////////////////////////////////////////////////////////////
339
340 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {}
341
342 // static
343 void WebsiteSettingsPopupView::ShowPopup(
344 views::View* anchor_view,
345 const gfx::Rect& anchor_rect,
346 Profile* profile,
347 content::WebContents* web_contents,
348 const GURL& url,
349 const security_state::SecurityInfo& security_info) {
350 gfx::NativeView parent_window =
351 anchor_view ? nullptr : web_contents->GetNativeView();
352 if (url.SchemeIs(content::kChromeUIScheme) ||
353 url.SchemeIs(content::kChromeDevToolsScheme) ||
354 url.SchemeIs(extensions::kExtensionScheme) ||
355 url.SchemeIs(content::kViewSourceScheme)) {
356 // Use the concrete type so that |SetAnchorRect| can be called as a friend.
357 InternalPageInfoPopupView* popup =
358 new InternalPageInfoPopupView(anchor_view, parent_window, url);
359 if (!anchor_view)
360 popup->SetAnchorRect(anchor_rect);
361 popup->GetWidget()->Show();
362 return;
363 }
364 WebsiteSettingsPopupView* popup = new WebsiteSettingsPopupView(
365 anchor_view, parent_window, profile, web_contents, url, security_info);
366 if (!anchor_view)
367 popup->SetAnchorRect(anchor_rect);
368 popup->GetWidget()->Show();
369 }
370
371 // static
372 WebsiteSettingsPopupView::PopupType
373 WebsiteSettingsPopupView::GetShownPopupType() {
374 return g_shown_popup_type;
375 }
376
377 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
378 views::View* anchor_view,
379 gfx::NativeView parent_window,
380 Profile* profile,
381 content::WebContents* web_contents,
382 const GURL& url,
383 const security_state::SecurityInfo& security_info)
384 : content::WebContentsObserver(web_contents),
385 BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
386 profile_(profile),
387 header_(nullptr),
388 separator_(nullptr),
389 site_settings_view_(nullptr),
390 cookies_view_(nullptr),
391 cookie_dialog_link_(nullptr),
392 permissions_view_(nullptr),
393 weak_factory_(this) {
394 g_shown_popup_type = POPUP_WEBSITE_SETTINGS;
395 set_parent_window(parent_window);
396
397 // Compensate for built-in vertical padding in the anchor view's image.
398 set_anchor_view_insets(gfx::Insets(
399 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
400
401 // Capture the default bubble margin, and move it to the Layout classes. This
402 // is necessary so that the views::Separator can extend the full width of the
403 // bubble.
404 const int side_margin = margins().left();
405 DCHECK_EQ(margins().left(), margins().right());
406
407 // Also remove the top margin from the client area so there is less space
408 // below the dialog title.
409 set_margins(gfx::Insets(0, 0, margins().bottom(), 0));
410
411 views::GridLayout* layout = new views::GridLayout(this);
412 SetLayoutManager(layout);
413
414 // Use a single ColumnSet here. Otherwise the preferred width doesn't properly
415 // propagate up to the dialog width.
416 const int content_column = 0;
417 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
418 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
419 views::GridLayout::USE_PREF, 0, 0);
420
421 header_ = new PopupHeaderView(this, this, side_margin);
422 layout->StartRow(1, content_column);
423 layout->AddView(header_);
424
425 layout->StartRow(0, content_column);
426 separator_ = new views::Separator();
427 layout->AddView(separator_);
428
429 layout->AddPaddingRow(1, kHeaderMarginBottom);
430 layout->StartRow(1, content_column);
431
432 site_settings_view_ = CreateSiteSettingsView(side_margin);
433 layout->AddView(site_settings_view_);
434
435 if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
436 // In non-material, titles are inset from the dialog margin. Ensure the
437 // horizontal insets match.
438 set_title_margins(
439 gfx::Insets(LayoutDelegate::Get()->GetMetric(
440 LayoutDelegate::Metric::PANEL_CONTENT_MARGIN),
441 side_margin, 0, side_margin));
442 }
443 views::BubbleDialogDelegateView::CreateBubble(this);
444
445 presenter_.reset(new WebsiteSettings(
446 this, profile, TabSpecificContentSettings::FromWebContents(web_contents),
447 web_contents, url, security_info));
448 }
449
450 void WebsiteSettingsPopupView::RenderFrameDeleted(
451 content::RenderFrameHost* render_frame_host) {
452 if (render_frame_host == web_contents()->GetMainFrame())
453 GetWidget()->Close();
454 }
455
456 void WebsiteSettingsPopupView::WebContentsDestroyed() {
457 weak_factory_.InvalidateWeakPtrs();
458 }
459
460 void WebsiteSettingsPopupView::OnPermissionChanged(
461 const WebsiteSettingsUI::PermissionInfo& permission) {
462 presenter_->OnSitePermissionChanged(permission.type, permission.setting);
463 // The menu buttons for the permissions might have longer strings now, so we
464 // need to layout and size the whole bubble.
465 Layout();
466 SizeToContents();
467 }
468
469 void WebsiteSettingsPopupView::OnChosenObjectDeleted(
470 const WebsiteSettingsUI::ChosenObjectInfo& info) {
471 presenter_->OnSiteChosenObjectDeleted(info.ui_info, *info.object);
472 }
473
474 base::string16 WebsiteSettingsPopupView::GetWindowTitle() const {
475 return summary_text_;
476 }
477
478 bool WebsiteSettingsPopupView::ShouldShowCloseButton() const {
479 return true;
480 }
481
482 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) {
483 g_shown_popup_type = POPUP_NONE;
484 presenter_->OnUIClosing();
485 }
486
487 int WebsiteSettingsPopupView::GetDialogButtons() const {
488 return ui::DIALOG_BUTTON_NONE;
489 }
490
491 const gfx::FontList& WebsiteSettingsPopupView::GetTitleFontList() const {
492 return ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
493 kSummaryFontSizeDelta);
494 }
495
496 void WebsiteSettingsPopupView::ButtonPressed(views::Button* button,
497 const ui::Event& event) {
498 DCHECK_EQ(BUTTON_CLOSE, button->id());
499 GetWidget()->Close();
500 }
501
502 void WebsiteSettingsPopupView::LinkClicked(views::Link* source,
503 int event_flags) {
504 // The popup closes automatically when the collected cookies dialog or the
505 // certificate viewer opens. So delay handling of the link clicked to avoid
506 // a crash in the base class which needs to complete the mouse event handling.
507 content::BrowserThread::PostTask(
508 content::BrowserThread::UI, FROM_HERE,
509 base::Bind(&WebsiteSettingsPopupView::HandleLinkClickedAsync,
510 weak_factory_.GetWeakPtr(), source));
511 }
512
513 gfx::Size WebsiteSettingsPopupView::GetPreferredSize() const {
514 if (header_ == nullptr && site_settings_view_ == nullptr)
515 return views::View::GetPreferredSize();
516
517 int height = 0;
518 if (header_)
519 height += header_->GetPreferredSize().height() + kHeaderMarginBottom;
520 if (separator_)
521 height += separator_->GetPreferredSize().height();
522
523 if (site_settings_view_)
524 height += site_settings_view_->GetPreferredSize().height();
525
526 int width = kMinPopupWidth;
527 if (site_settings_view_)
528 width = std::max(width, site_settings_view_->GetPreferredSize().width());
529 width = std::min(width, kMaxPopupWidth);
530 return gfx::Size(width, height);
531 }
532
533 void WebsiteSettingsPopupView::SetCookieInfo(
534 const CookieInfoList& cookie_info_list) {
535 // |cookie_info_list| should only ever have 2 items: first- and third-party
536 // cookies.
537 DCHECK_EQ(cookie_info_list.size(), 2u);
538 int total_allowed = 0;
539 for (const auto& i : cookie_info_list)
540 total_allowed += i.allowed;
541 base::string16 label_text = l10n_util::GetPluralStringFUTF16(
542 IDS_WEBSITE_SETTINGS_NUM_COOKIES, total_allowed);
543
544 if (!cookie_dialog_link_) {
545 cookie_dialog_link_ = new views::Link(label_text);
546 cookie_dialog_link_->set_id(LINK_COOKIE_DIALOG);
547 cookie_dialog_link_->set_listener(this);
548 } else {
549 cookie_dialog_link_->SetText(label_text);
550 }
551
552 views::GridLayout* layout =
553 static_cast<views::GridLayout*>(cookies_view_->GetLayoutManager());
554 if (!layout) {
555 layout = new views::GridLayout(cookies_view_);
556 cookies_view_->SetLayoutManager(layout);
557
558 const int cookies_view_column = 0;
559 views::ColumnSet* column_set = layout->AddColumnSet(cookies_view_column);
560 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
561 views::GridLayout::FIXED, kPermissionIconColumnWidth,
562 0);
563 column_set->AddPaddingColumn(0, kPermissionImageSpacing);
564 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL,
565 0, views::GridLayout::USE_PREF, 0, 0);
566
567 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
568
569 layout->StartRow(1, cookies_view_column);
570 WebsiteSettingsUI::PermissionInfo info;
571 info.type = CONTENT_SETTINGS_TYPE_COOKIES;
572 info.setting = CONTENT_SETTING_ALLOW;
573 info.is_incognito =
574 Profile::FromBrowserContext(web_contents()->GetBrowserContext())
575 ->IsOffTheRecord();
576 views::ImageView* icon = new NonAccessibleImageView();
577 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(info);
578 icon->SetImage(image.ToImageSkia());
579 layout->AddView(
580 icon, 1, 2, views::GridLayout::FILL,
581 // TODO: The vertical alignment may change to CENTER once Harmony is
582 // implemented. See https://crbug.com/512442#c48
583 views::GridLayout::LEADING);
584
585 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
586 const gfx::FontList& font_list = rb.GetFontListWithDelta(1);
587 views::Label* cookies_label = new views::Label(
588 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA),
589 font_list);
590 layout->AddView(cookies_label);
591 layout->StartRow(1, cookies_view_column);
592 layout->SkipColumns(1);
593
594 layout->AddView(cookie_dialog_link_);
595
596 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
597 }
598
599 layout->Layout(cookies_view_);
600 SizeToContents();
601 }
602
603 void WebsiteSettingsPopupView::SetPermissionInfo(
604 const PermissionInfoList& permission_info_list,
605 ChosenObjectInfoList chosen_object_info_list) {
606 // When a permission is changed, WebsiteSettings::OnSitePermissionChanged()
607 // calls this method with updated permissions. However, PermissionSelectorRow
608 // will have already updated its state, so it's already reflected in the UI.
609 // In addition, if a permission is set to the default setting, WebsiteSettings
610 // removes it from |permission_info_list|, but the button should remain.
611 if (permissions_view_)
612 return;
613
614 permissions_view_ = new views::View();
615 views::GridLayout* layout = new views::GridLayout(permissions_view_);
616 permissions_view_->SetLayoutManager(layout);
617
618 site_settings_view_->AddChildView(permissions_view_);
619
620 const int content_column = 0;
621 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
622 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
623 views::GridLayout::USE_PREF, 0, 0);
624 const int permissions_column = 1;
625 views::ColumnSet* permissions_set = layout->AddColumnSet(permissions_column);
626 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
627 0, views::GridLayout::FIXED,
628 kPermissionIconColumnWidth, 0);
629 permissions_set->AddPaddingColumn(0, kPermissionIconMarginLeft);
630 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
631 0, views::GridLayout::USE_PREF, 0, 0);
632 permissions_set->AddPaddingColumn(1, kPermissionMenuSpacing);
633 permissions_set->AddColumn(views::GridLayout::TRAILING,
634 views::GridLayout::FILL, 0,
635 views::GridLayout::USE_PREF, 0, 0);
636 for (const auto& permission : permission_info_list) {
637 layout->StartRow(1, permissions_column);
638 std::unique_ptr<PermissionSelectorRow> selector =
639 base::MakeUnique<PermissionSelectorRow>(
640 profile_,
641 web_contents() ? web_contents()->GetVisibleURL()
642 : GURL::EmptyGURL(),
643 permission, layout);
644 selector->AddObserver(this);
645 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
646 selector_rows_.push_back(std::move(selector));
647 }
648
649 for (auto& object : chosen_object_info_list) {
650 layout->StartRow(1, content_column);
651 // The view takes ownership of the object info.
652 auto* object_view = new ChosenObjectRow(std::move(object));
653 object_view->AddObserver(this);
654 layout->AddView(object_view, 1, 1, views::GridLayout::LEADING,
655 views::GridLayout::CENTER);
656 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
657 }
658
659 layout->Layout(permissions_view_);
660
661 // Add site settings link.
662 views::Link* site_settings_link = new views::Link(
663 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_SETTINGS_LINK));
664 site_settings_link->set_id(LINK_SITE_SETTINGS);
665 site_settings_link->set_listener(this);
666 views::View* link_section = new views::View();
667 const int kLinkMarginTop = 4;
668 link_section->SetLayoutManager(new views::BoxLayout(
669 views::BoxLayout::kHorizontal, 0, kLinkMarginTop, 0));
670 link_section->AddChildView(site_settings_link);
671 site_settings_view_->AddChildView(link_section);
672
673 SizeToContents();
674 }
675
676 void WebsiteSettingsPopupView::SetIdentityInfo(
677 const IdentityInfo& identity_info) {
678 std::unique_ptr<WebsiteSettingsUI::SecurityDescription> security_description =
679 identity_info.GetSecurityDescription();
680
681 summary_text_ = security_description->summary;
682 GetWidget()->UpdateWindowTitle();
683
684 if (identity_info.certificate) {
685 certificate_ = identity_info.certificate;
686
687 if (identity_info.show_ssl_decision_revoke_button)
688 header_->AddResetDecisionsLabel();
689 }
690
691 header_->SetDetails(security_description->details);
692
693 Layout();
694 SizeToContents();
695 }
696
697 views::View* WebsiteSettingsPopupView::CreateSiteSettingsView(int side_margin) {
698 views::View* site_settings_view = new views::View();
699 views::BoxLayout* box_layout =
700 new views::BoxLayout(views::BoxLayout::kVertical, side_margin, 0, 0);
701 site_settings_view->SetLayoutManager(box_layout);
702 box_layout->set_cross_axis_alignment(
703 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
704
705 // Add cookies view.
706 cookies_view_ = new views::View();
707 site_settings_view->AddChildView(cookies_view_);
708
709 return site_settings_view;
710 }
711
712 void WebsiteSettingsPopupView::HandleLinkClickedAsync(views::Link* source) {
713 // Both switch cases require accessing web_contents(), so we check it here.
714 if (web_contents() == nullptr || web_contents()->IsBeingDestroyed())
715 return;
716 switch (source->id()) {
717 case LINK_SITE_SETTINGS:
718 // TODO(crbug.com/655876): This opens the general Content Settings pane,
719 // which is OK for now. But on Android, it opens a page specific to a
720 // given origin that shows all of the settings for that origin. If/when
721 // that's available on desktop we should link to that here, too.
722 web_contents()->OpenURL(content::OpenURLParams(
723 GURL(chrome::kChromeUIContentSettingsURL), content::Referrer(),
724 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
725 false));
726 presenter_->RecordWebsiteSettingsAction(
727 WebsiteSettings::WEBSITE_SETTINGS_SITE_SETTINGS_OPENED);
728 break;
729 case LINK_COOKIE_DIALOG:
730 // Count how often the Collected Cookies dialog is opened.
731 presenter_->RecordWebsiteSettingsAction(
732 WebsiteSettings::WEBSITE_SETTINGS_COOKIES_DIALOG_OPENED);
733 new CollectedCookiesViews(web_contents());
734 break;
735 default:
736 NOTREACHED();
737 }
738 }
739
740 void WebsiteSettingsPopupView::StyledLabelLinkClicked(views::StyledLabel* label,
741 const gfx::Range& range,
742 int event_flags) {
743 switch (label->id()) {
744 case STYLED_LABEL_SECURITY_DETAILS:
745 web_contents()->OpenURL(content::OpenURLParams(
746 GURL(chrome::kPageInfoHelpCenterURL), content::Referrer(),
747 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
748 false));
749 presenter_->RecordWebsiteSettingsAction(
750 WebsiteSettings::WEBSITE_SETTINGS_CONNECTION_HELP_OPENED);
751 break;
752 case STYLED_LABEL_RESET_CERTIFICATE_DECISIONS:
753 presenter_->OnRevokeSSLErrorBypassButtonPressed();
754 GetWidget()->Close();
755 break;
756 default:
757 NOTREACHED();
758 }
759 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698