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

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

Powered by Google App Engine
This is Rietveld 408576698