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

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

Issue 2744933002: Move Views Page Info UI code to its own folder. (Closed)
Patch Set: *shakes other fist at mass-rename.py* 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/website_settings/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/website_settings/chosen_object_row.h"
28 #include "chrome/browser/ui/views/website_settings/non_accessible_image_view.h"
29 #include "chrome/browser/ui/views/website_settings/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
329 void InternalPageInfoPopupView::OnWidgetDestroying(views::Widget* widget) {
330 g_shown_popup_type = WebsiteSettingsPopupView::POPUP_NONE;
331 }
332
333 int InternalPageInfoPopupView::GetDialogButtons() const {
334 return ui::DIALOG_BUTTON_NONE;
335 }
336
337 ////////////////////////////////////////////////////////////////////////////////
338 // WebsiteSettingsPopupView
339 ////////////////////////////////////////////////////////////////////////////////
340
341 WebsiteSettingsPopupView::~WebsiteSettingsPopupView() {
342 }
343
344 // static
345 void WebsiteSettingsPopupView::ShowPopup(
346 views::View* anchor_view,
347 const gfx::Rect& anchor_rect,
348 Profile* profile,
349 content::WebContents* web_contents,
350 const GURL& url,
351 const security_state::SecurityInfo& security_info) {
352 gfx::NativeView parent_window =
353 anchor_view ? nullptr : web_contents->GetNativeView();
354 if (url.SchemeIs(content::kChromeUIScheme) ||
355 url.SchemeIs(content::kChromeDevToolsScheme) ||
356 url.SchemeIs(extensions::kExtensionScheme) ||
357 url.SchemeIs(content::kViewSourceScheme)) {
358 // Use the concrete type so that |SetAnchorRect| can be called as a friend.
359 InternalPageInfoPopupView* popup =
360 new InternalPageInfoPopupView(anchor_view, parent_window, url);
361 if (!anchor_view)
362 popup->SetAnchorRect(anchor_rect);
363 popup->GetWidget()->Show();
364 return;
365 }
366 WebsiteSettingsPopupView* popup = new WebsiteSettingsPopupView(
367 anchor_view, parent_window, profile, web_contents, url, security_info);
368 if (!anchor_view)
369 popup->SetAnchorRect(anchor_rect);
370 popup->GetWidget()->Show();
371 }
372
373 // static
374 WebsiteSettingsPopupView::PopupType
375 WebsiteSettingsPopupView::GetShownPopupType() {
376 return g_shown_popup_type;
377 }
378
379 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
380 views::View* anchor_view,
381 gfx::NativeView parent_window,
382 Profile* profile,
383 content::WebContents* web_contents,
384 const GURL& url,
385 const security_state::SecurityInfo& security_info)
386 : content::WebContentsObserver(web_contents),
387 BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
388 profile_(profile),
389 header_(nullptr),
390 separator_(nullptr),
391 site_settings_view_(nullptr),
392 cookies_view_(nullptr),
393 cookie_dialog_link_(nullptr),
394 permissions_view_(nullptr),
395 weak_factory_(this) {
396 g_shown_popup_type = POPUP_WEBSITE_SETTINGS;
397 set_parent_window(parent_window);
398
399 // Compensate for built-in vertical padding in the anchor view's image.
400 set_anchor_view_insets(gfx::Insets(
401 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
402
403 // Capture the default bubble margin, and move it to the Layout classes. This
404 // is necessary so that the views::Separator can extend the full width of the
405 // bubble.
406 const int side_margin = margins().left();
407 DCHECK_EQ(margins().left(), margins().right());
408
409 // Also remove the top margin from the client area so there is less space
410 // below the dialog title.
411 set_margins(gfx::Insets(0, 0, margins().bottom(), 0));
412
413 views::GridLayout* layout = new views::GridLayout(this);
414 SetLayoutManager(layout);
415
416 // Use a single ColumnSet here. Otherwise the preferred width doesn't properly
417 // propagate up to the dialog width.
418 const int content_column = 0;
419 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
420 column_set->AddColumn(views::GridLayout::FILL,
421 views::GridLayout::FILL,
422 1,
423 views::GridLayout::USE_PREF,
424 0,
425 0);
426
427 header_ = new PopupHeaderView(this, this, side_margin);
428 layout->StartRow(1, content_column);
429 layout->AddView(header_);
430
431 layout->StartRow(0, content_column);
432 separator_ = new views::Separator();
433 layout->AddView(separator_);
434
435 layout->AddPaddingRow(1, kHeaderMarginBottom);
436 layout->StartRow(1, content_column);
437
438 site_settings_view_ = CreateSiteSettingsView(side_margin);
439 layout->AddView(site_settings_view_);
440
441 if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
442 // In non-material, titles are inset from the dialog margin. Ensure the
443 // horizontal insets match.
444 set_title_margins(
445 gfx::Insets(LayoutDelegate::Get()->GetMetric(
446 LayoutDelegate::Metric::PANEL_CONTENT_MARGIN),
447 side_margin, 0, side_margin));
448 }
449 views::BubbleDialogDelegateView::CreateBubble(this);
450
451 presenter_.reset(new WebsiteSettings(
452 this, profile, TabSpecificContentSettings::FromWebContents(web_contents),
453 web_contents, url, security_info));
454 }
455
456 void WebsiteSettingsPopupView::RenderFrameDeleted(
457 content::RenderFrameHost* render_frame_host) {
458 if (render_frame_host == web_contents()->GetMainFrame())
459 GetWidget()->Close();
460 }
461
462 void WebsiteSettingsPopupView::WebContentsDestroyed() {
463 weak_factory_.InvalidateWeakPtrs();
464 }
465
466 void WebsiteSettingsPopupView::OnPermissionChanged(
467 const WebsiteSettingsUI::PermissionInfo& permission) {
468 presenter_->OnSitePermissionChanged(permission.type, permission.setting);
469 // The menu buttons for the permissions might have longer strings now, so we
470 // need to layout and size the whole bubble.
471 Layout();
472 SizeToContents();
473 }
474
475 void WebsiteSettingsPopupView::OnChosenObjectDeleted(
476 const WebsiteSettingsUI::ChosenObjectInfo& info) {
477 presenter_->OnSiteChosenObjectDeleted(info.ui_info, *info.object);
478 }
479
480 base::string16 WebsiteSettingsPopupView::GetWindowTitle() const {
481 return summary_text_;
482 }
483
484 bool WebsiteSettingsPopupView::ShouldShowCloseButton() const {
485 return true;
486 }
487
488 void WebsiteSettingsPopupView::OnWidgetDestroying(views::Widget* widget) {
489 g_shown_popup_type = POPUP_NONE;
490 presenter_->OnUIClosing();
491 }
492
493 int WebsiteSettingsPopupView::GetDialogButtons() const {
494 return ui::DIALOG_BUTTON_NONE;
495 }
496
497 const gfx::FontList& WebsiteSettingsPopupView::GetTitleFontList() const {
498 return ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
499 kSummaryFontSizeDelta);
500 }
501
502 void WebsiteSettingsPopupView::ButtonPressed(views::Button* button,
503 const ui::Event& event) {
504 DCHECK_EQ(BUTTON_CLOSE, button->id());
505 GetWidget()->Close();
506 }
507
508 void WebsiteSettingsPopupView::LinkClicked(views::Link* source,
509 int event_flags) {
510 // The popup closes automatically when the collected cookies dialog or the
511 // certificate viewer opens. So delay handling of the link clicked to avoid
512 // a crash in the base class which needs to complete the mouse event handling.
513 content::BrowserThread::PostTask(
514 content::BrowserThread::UI, FROM_HERE,
515 base::Bind(&WebsiteSettingsPopupView::HandleLinkClickedAsync,
516 weak_factory_.GetWeakPtr(), source));
517 }
518
519 gfx::Size WebsiteSettingsPopupView::GetPreferredSize() const {
520 if (header_ == nullptr && site_settings_view_ == nullptr)
521 return views::View::GetPreferredSize();
522
523 int height = 0;
524 if (header_)
525 height += header_->GetPreferredSize().height() + kHeaderMarginBottom;
526 if (separator_)
527 height += separator_->GetPreferredSize().height();
528
529 if (site_settings_view_)
530 height += site_settings_view_->GetPreferredSize().height();
531
532 int width = kMinPopupWidth;
533 if (site_settings_view_)
534 width = std::max(width, site_settings_view_->GetPreferredSize().width());
535 width = std::min(width, kMaxPopupWidth);
536 return gfx::Size(width, height);
537 }
538
539 void WebsiteSettingsPopupView::SetCookieInfo(
540 const CookieInfoList& cookie_info_list) {
541 // |cookie_info_list| should only ever have 2 items: first- and third-party
542 // cookies.
543 DCHECK_EQ(cookie_info_list.size(), 2u);
544 int total_allowed = 0;
545 for (const auto& i : cookie_info_list)
546 total_allowed += i.allowed;
547 base::string16 label_text = l10n_util::GetPluralStringFUTF16(
548 IDS_WEBSITE_SETTINGS_NUM_COOKIES, total_allowed);
549
550 if (!cookie_dialog_link_) {
551 cookie_dialog_link_ = new views::Link(label_text);
552 cookie_dialog_link_->set_id(LINK_COOKIE_DIALOG);
553 cookie_dialog_link_->set_listener(this);
554 } else {
555 cookie_dialog_link_->SetText(label_text);
556 }
557
558 views::GridLayout* layout =
559 static_cast<views::GridLayout*>(cookies_view_->GetLayoutManager());
560 if (!layout) {
561 layout = new views::GridLayout(cookies_view_);
562 cookies_view_->SetLayoutManager(layout);
563
564 const int cookies_view_column = 0;
565 views::ColumnSet* column_set = layout->AddColumnSet(cookies_view_column);
566 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
567 views::GridLayout::FIXED, kPermissionIconColumnWidth,
568 0);
569 column_set->AddPaddingColumn(0, kPermissionImageSpacing);
570 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL,
571 0, views::GridLayout::USE_PREF, 0, 0);
572
573 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
574
575 layout->StartRow(1, cookies_view_column);
576 WebsiteSettingsUI::PermissionInfo info;
577 info.type = CONTENT_SETTINGS_TYPE_COOKIES;
578 info.setting = CONTENT_SETTING_ALLOW;
579 info.is_incognito =
580 Profile::FromBrowserContext(web_contents()->GetBrowserContext())
581 ->IsOffTheRecord();
582 views::ImageView* icon = new NonAccessibleImageView();
583 const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(info);
584 icon->SetImage(image.ToImageSkia());
585 layout->AddView(
586 icon, 1, 2, views::GridLayout::FILL,
587 // TODO: The vertical alignment may change to CENTER once Harmony is
588 // implemented. See https://crbug.com/512442#c48
589 views::GridLayout::LEADING);
590
591 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
592 const gfx::FontList& font_list = rb.GetFontListWithDelta(1);
593 views::Label* cookies_label = new views::Label(
594 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TITLE_SITE_DATA),
595 font_list);
596 layout->AddView(cookies_label);
597 layout->StartRow(1, cookies_view_column);
598 layout->SkipColumns(1);
599
600 layout->AddView(cookie_dialog_link_);
601
602 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
603 }
604
605 layout->Layout(cookies_view_);
606 SizeToContents();
607 }
608
609 void WebsiteSettingsPopupView::SetPermissionInfo(
610 const PermissionInfoList& permission_info_list,
611 ChosenObjectInfoList chosen_object_info_list) {
612 // When a permission is changed, WebsiteSettings::OnSitePermissionChanged()
613 // calls this method with updated permissions. However, PermissionSelectorRow
614 // will have already updated its state, so it's already reflected in the UI.
615 // In addition, if a permission is set to the default setting, WebsiteSettings
616 // removes it from |permission_info_list|, but the button should remain.
617 if (permissions_view_)
618 return;
619
620 permissions_view_ = new views::View();
621 views::GridLayout* layout = new views::GridLayout(permissions_view_);
622 permissions_view_->SetLayoutManager(layout);
623
624 site_settings_view_->AddChildView(permissions_view_);
625
626 const int content_column = 0;
627 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
628 column_set->AddColumn(views::GridLayout::FILL,
629 views::GridLayout::FILL,
630 1,
631 views::GridLayout::USE_PREF,
632 0,
633 0);
634 const int permissions_column = 1;
635 views::ColumnSet* permissions_set = layout->AddColumnSet(permissions_column);
636 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
637 0, views::GridLayout::FIXED,
638 kPermissionIconColumnWidth, 0);
639 permissions_set->AddPaddingColumn(0, kPermissionIconMarginLeft);
640 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
641 0, views::GridLayout::USE_PREF, 0, 0);
642 permissions_set->AddPaddingColumn(1, kPermissionMenuSpacing);
643 permissions_set->AddColumn(views::GridLayout::TRAILING,
644 views::GridLayout::FILL, 0,
645 views::GridLayout::USE_PREF, 0, 0);
646 for (const auto& permission : permission_info_list) {
647 layout->StartRow(1, permissions_column);
648 std::unique_ptr<PermissionSelectorRow> selector =
649 base::MakeUnique<PermissionSelectorRow>(
650 profile_,
651 web_contents() ? web_contents()->GetVisibleURL()
652 : GURL::EmptyGURL(),
653 permission, layout);
654 selector->AddObserver(this);
655 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
656 selector_rows_.push_back(std::move(selector));
657 }
658
659 for (auto& object : chosen_object_info_list) {
660 layout->StartRow(1, content_column);
661 // The view takes ownership of the object info.
662 auto* object_view = new ChosenObjectRow(std::move(object));
663 object_view->AddObserver(this);
664 layout->AddView(object_view, 1, 1, views::GridLayout::LEADING,
665 views::GridLayout::CENTER);
666 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
667 }
668
669 layout->Layout(permissions_view_);
670
671 // Add site settings link.
672 views::Link* site_settings_link = new views::Link(
673 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_SETTINGS_LINK));
674 site_settings_link->set_id(LINK_SITE_SETTINGS);
675 site_settings_link->set_listener(this);
676 views::View* link_section = new views::View();
677 const int kLinkMarginTop = 4;
678 link_section->SetLayoutManager(new views::BoxLayout(
679 views::BoxLayout::kHorizontal, 0, kLinkMarginTop, 0));
680 link_section->AddChildView(site_settings_link);
681 site_settings_view_->AddChildView(link_section);
682
683 SizeToContents();
684 }
685
686 void WebsiteSettingsPopupView::SetIdentityInfo(
687 const IdentityInfo& identity_info) {
688 std::unique_ptr<WebsiteSettingsUI::SecurityDescription> security_description =
689 identity_info.GetSecurityDescription();
690
691 summary_text_ = security_description->summary;
692 GetWidget()->UpdateWindowTitle();
693
694 if (identity_info.certificate) {
695 certificate_ = identity_info.certificate;
696
697 if (identity_info.show_ssl_decision_revoke_button)
698 header_->AddResetDecisionsLabel();
699 }
700
701 header_->SetDetails(security_description->details);
702
703 Layout();
704 SizeToContents();
705 }
706
707 views::View* WebsiteSettingsPopupView::CreateSiteSettingsView(int side_margin) {
708 views::View* site_settings_view = new views::View();
709 views::BoxLayout* box_layout =
710 new views::BoxLayout(views::BoxLayout::kVertical, side_margin, 0, 0);
711 site_settings_view->SetLayoutManager(box_layout);
712 box_layout->set_cross_axis_alignment(
713 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
714
715 // Add cookies view.
716 cookies_view_ = new views::View();
717 site_settings_view->AddChildView(cookies_view_);
718
719 return site_settings_view;
720 }
721
722 void WebsiteSettingsPopupView::HandleLinkClickedAsync(views::Link* source) {
723 // Both switch cases require accessing web_contents(), so we check it here.
724 if (web_contents() == nullptr || web_contents()->IsBeingDestroyed())
725 return;
726 switch (source->id()) {
727 case LINK_SITE_SETTINGS:
728 // TODO(crbug.com/655876): This opens the general Content Settings pane,
729 // which is OK for now. But on Android, it opens a page specific to a
730 // given origin that shows all of the settings for that origin. If/when
731 // that's available on desktop we should link to that here, too.
732 web_contents()->OpenURL(content::OpenURLParams(
733 GURL(chrome::kChromeUIContentSettingsURL), content::Referrer(),
734 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
735 false));
736 presenter_->RecordWebsiteSettingsAction(
737 WebsiteSettings::WEBSITE_SETTINGS_SITE_SETTINGS_OPENED);
738 break;
739 case LINK_COOKIE_DIALOG:
740 // Count how often the Collected Cookies dialog is opened.
741 presenter_->RecordWebsiteSettingsAction(
742 WebsiteSettings::WEBSITE_SETTINGS_COOKIES_DIALOG_OPENED);
743 new CollectedCookiesViews(web_contents());
744 break;
745 default:
746 NOTREACHED();
747 }
748 }
749
750 void WebsiteSettingsPopupView::StyledLabelLinkClicked(views::StyledLabel* label,
751 const gfx::Range& range,
752 int event_flags) {
753 switch (label->id()) {
754 case STYLED_LABEL_SECURITY_DETAILS:
755 web_contents()->OpenURL(content::OpenURLParams(
756 GURL(chrome::kPageInfoHelpCenterURL), content::Referrer(),
757 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
758 false));
759 presenter_->RecordWebsiteSettingsAction(
760 WebsiteSettings::WEBSITE_SETTINGS_CONNECTION_HELP_OPENED);
761 break;
762 case STYLED_LABEL_RESET_CERTIFICATE_DECISIONS:
763 presenter_->OnRevokeSSLErrorBypassButtonPressed();
764 GetWidget()->Close();
765 break;
766 default:
767 NOTREACHED();
768 }
769 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698