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

Side by Side Diff: chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.cc

Issue 1330423003: [Extensions Toolbar] Protect against crazy bounds (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Peter's Created 5 years, 3 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h" 5 #include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h" 10 #include "base/thread_task_runner_handle.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" 12 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
13 #include "chrome/browser/ui/views/frame/browser_view.h" 13 #include "chrome/browser/ui/views/frame/browser_view.h"
14 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" 14 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
15 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" 15 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
16 #include "chrome/browser/ui/views/toolbar/wrench_menu.h" 16 #include "chrome/browser/ui/views/toolbar/wrench_menu.h"
17 #include "ui/views/controls/menu/menu_item_view.h" 17 #include "ui/views/controls/menu/menu_item_view.h"
18 #include "ui/views/controls/menu/submenu_view.h" 18 #include "ui/views/controls/menu/submenu_view.h"
19 19
20 ExtensionToolbarMenuView::ExtensionToolbarMenuView(Browser* browser, 20 ExtensionToolbarMenuView::ExtensionToolbarMenuView(Browser* browser,
21 WrenchMenu* wrench_menu) 21 WrenchMenu* wrench_menu)
22 : browser_(browser), 22 : browser_(browser),
23 wrench_menu_(wrench_menu), 23 wrench_menu_(wrench_menu),
24 container_(NULL), 24 container_(nullptr),
25 max_height_(0),
25 browser_actions_container_observer_(this), 26 browser_actions_container_observer_(this),
26 weak_factory_(this) { 27 weak_factory_(this) {
27 BrowserActionsContainer* main = 28 BrowserActionsContainer* main =
28 BrowserView::GetBrowserViewForBrowser(browser_) 29 BrowserView::GetBrowserViewForBrowser(browser_)
29 ->toolbar()->browser_actions(); 30 ->toolbar()->browser_actions();
30 container_ = new BrowserActionsContainer(browser_, main); 31 container_ = new BrowserActionsContainer(browser_, main);
31 container_->Init(); 32 container_->Init();
32 AddChildView(container_); 33 SetContents(container_);
33 // We Layout() the container here so that we know the number of actions 34 // We Layout() the container here so that we know the number of actions
34 // that will be visible in ShouldShow(). 35 // that will be visible in ShouldShow().
35 container_->Layout(); 36 container_->Layout();
36 37
37 // If we were opened for a drop command, we have to wait for the drop to 38 // If we were opened for a drop command, we have to wait for the drop to
38 // finish so we can close the wrench menu. 39 // finish so we can close the wrench menu.
39 if (wrench_menu_->for_drop()) { 40 if (wrench_menu_->for_drop()) {
40 browser_actions_container_observer_.Add(container_); 41 browser_actions_container_observer_.Add(container_);
41 browser_actions_container_observer_.Add(main); 42 browser_actions_container_observer_.Add(main);
42 } 43 }
44
45 // In *very* extreme cases, it's possible that there are so many overflowed
46 // actions, we won't be able to show them all. Cap the height so that the
47 // overflow won't make the menu larger than the height of the screen.
48 // Note: As of Sept. 2015, we can show 104 actions, so less than 0.0002% of
49 // our users will be affected.
50 max_height_ = ToolbarActionsBar::IconHeight() * 1;
Peter Kasting 2015/09/17 00:18:04 I'm confused. Does this mean one row of icons? H
Devlin 2015/09/17 17:00:27 D'oh. Was testing to make sure it worked (and did
51 ClipHeightTo(0, max_height_);
43 } 52 }
44 53
45 ExtensionToolbarMenuView::~ExtensionToolbarMenuView() { 54 ExtensionToolbarMenuView::~ExtensionToolbarMenuView() {
46 } 55 }
47 56
48 bool ExtensionToolbarMenuView::ShouldShow() { 57 bool ExtensionToolbarMenuView::ShouldShow() {
49 return wrench_menu_->for_drop() || 58 return wrench_menu_->for_drop() ||
50 container_->VisibleBrowserActionsAfterAnimation(); 59 container_->VisibleBrowserActionsAfterAnimation();
51 } 60 }
52 61
53 gfx::Size ExtensionToolbarMenuView::GetPreferredSize() const { 62 gfx::Size ExtensionToolbarMenuView::GetPreferredSize() const {
54 return container_->GetPreferredSize(); 63 gfx::Size s = views::ScrollView::GetPreferredSize();
64 // views::ScrollView::GetPreferredSize() includes the contents' size, but
65 // not the scrollbar width. Add it in if necessary.
Peter Kasting 2015/09/17 00:18:04 I wonder if we should fix this in ScrollView.
Devlin 2015/09/17 17:00:27 That would make me concerned about breaking anythi
66 if (container_->GetPreferredSize().height() > max_height_)
67 s.set_width(s.width() + GetScrollBarWidth());
Peter Kasting 2015/09/17 00:18:04 Nit: s.Enlarge(GetScrollbarWidth(), 0));
Devlin 2015/09/17 17:00:27 Done.
68 return s;
55 } 69 }
56 70
57 int ExtensionToolbarMenuView::GetHeightForWidth(int width) const { 71 int ExtensionToolbarMenuView::GetHeightForWidth(int width) const {
72 // The width passed in here includes the full width of the menu, so we need
73 // to omit the necessary padding.
58 const views::MenuConfig& menu_config = 74 const views::MenuConfig& menu_config =
59 static_cast<const views::MenuItemView*>(parent())->GetMenuConfig(); 75 static_cast<const views::MenuItemView*>(parent())->GetMenuConfig();
60 int end_padding = menu_config.arrow_to_edge_padding - 76 int end_padding = menu_config.arrow_to_edge_padding -
61 container_->toolbar_actions_bar()->platform_settings().item_spacing; 77 container_->toolbar_actions_bar()->platform_settings().item_spacing;
62 width -= start_padding() + end_padding; 78 width -= start_padding() + end_padding;
63 79
64 int height = container_->GetHeightForWidth(width); 80 return views::ScrollView::GetHeightForWidth(width);
Peter Kasting 2015/09/17 00:18:04 (Does this include the scrollbar width in the calc
Devlin 2015/09/17 17:00:27 Yes.
65 return height;
66 } 81 }
67 82
68 void ExtensionToolbarMenuView::Layout() { 83 void ExtensionToolbarMenuView::Layout() {
69 gfx::Size sz = GetPreferredSize(); 84 SetPosition(gfx::Point(start_padding() + 1, 0));
Peter Kasting 2015/09/17 00:18:04 Why +1?
Devlin 2015/09/17 17:00:27 It was because the start_padding() was returning t
70 SetBounds(start_padding() + 1, 0, sz.width(), sz.height()); 85 SizeToPreferredSize();
71 container_->SetBounds(0, 0, sz.width(), sz.height()); 86 views::ScrollView::Layout();
72 } 87 }
73 88
74 void ExtensionToolbarMenuView::OnBrowserActionDragDone() { 89 void ExtensionToolbarMenuView::OnBrowserActionDragDone() {
75 // The delay before we close the wrench menu if this was opened for a drop so 90 // The delay before we close the wrench menu if this was opened for a drop so
76 // that the user can see a browser action if one was moved. 91 // that the user can see a browser action if one was moved.
77 static const int kCloseMenuDelay = 300; 92 static const int kCloseMenuDelay = 300;
78 93
79 DCHECK(wrench_menu_->for_drop()); 94 DCHECK(wrench_menu_->for_drop());
80 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 95 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
81 FROM_HERE, base::Bind(&ExtensionToolbarMenuView::CloseWrenchMenu, 96 FROM_HERE, base::Bind(&ExtensionToolbarMenuView::CloseWrenchMenu,
82 weak_factory_.GetWeakPtr()), 97 weak_factory_.GetWeakPtr()),
83 base::TimeDelta::FromMilliseconds(kCloseMenuDelay)); 98 base::TimeDelta::FromMilliseconds(kCloseMenuDelay));
84 } 99 }
85 100
86 void ExtensionToolbarMenuView::CloseWrenchMenu() { 101 void ExtensionToolbarMenuView::CloseWrenchMenu() {
87 wrench_menu_->CloseMenu(); 102 wrench_menu_->CloseMenu();
88 } 103 }
89 104
90 int ExtensionToolbarMenuView::start_padding() const { 105 int ExtensionToolbarMenuView::start_padding() const {
91 // We pad enough on the left so that the first icon starts at the same point 106 // We pad enough on the left so that the first icon starts at the same point
92 // as the labels. We need to subtract 1 because we want the pixel *before* 107 // as the labels. We need to subtract 1 because we want the pixel *before*
93 // the label, and we subtract kItemSpacing because there needs to be padding 108 // the label, and we subtract kItemSpacing because there needs to be padding
94 // so we can see the drop indicator. 109 // so we can see the drop indicator.
95 return views::MenuItemView::label_start() - 1 - 110 return views::MenuItemView::label_start() - 1 -
96 container_->toolbar_actions_bar()->platform_settings().item_spacing; 111 container_->toolbar_actions_bar()->platform_settings().item_spacing;
97 } 112 }
98 113
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698