OLD | NEW |
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/website_settings/permissions_bubble_view.h" | 5 #include "chrome/browser/ui/views/website_settings/permissions_bubble_view.h" |
6 | 6 |
| 7 #include "base/prefs/pref_service.h" |
7 #include "base/strings/string16.h" | 8 #include "base/strings/string16.h" |
| 9 #include "chrome/browser/profiles/profile.h" |
| 10 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/ui/views/exclusive_access_bubble_views.h" |
| 12 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 13 #include "chrome/browser/ui/views/frame/top_container_view.h" |
| 14 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 15 #include "chrome/browser/ui/views/location_bar/location_icon_view.h" |
8 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h" | 16 #include "chrome/browser/ui/views/website_settings/permission_selector_view.h" |
9 #include "chrome/browser/ui/views/website_settings/permission_selector_view_obse
rver.h" | 17 #include "chrome/browser/ui/views/website_settings/permission_selector_view_obse
rver.h" |
10 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" | 18 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" |
| 19 #include "chrome/common/pref_names.h" |
11 #include "chrome/grit/generated_resources.h" | 20 #include "chrome/grit/generated_resources.h" |
12 #include "net/base/net_util.h" | 21 #include "net/base/net_util.h" |
13 #include "ui/accessibility/ax_view_state.h" | 22 #include "ui/accessibility/ax_view_state.h" |
14 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
15 #include "ui/base/models/combobox_model.h" | 24 #include "ui/base/models/combobox_model.h" |
16 #include "ui/base/resource/resource_bundle.h" | 25 #include "ui/base/resource/resource_bundle.h" |
17 #include "ui/gfx/text_constants.h" | 26 #include "ui/gfx/text_constants.h" |
18 #include "ui/views/bubble/bubble_delegate.h" | 27 #include "ui/views/bubble/bubble_delegate.h" |
| 28 #include "ui/views/bubble/bubble_frame_view.h" |
19 #include "ui/views/controls/button/checkbox.h" | 29 #include "ui/views/controls/button/checkbox.h" |
20 #include "ui/views/controls/button/label_button.h" | 30 #include "ui/views/controls/button/label_button.h" |
21 #include "ui/views/controls/button/label_button_border.h" | 31 #include "ui/views/controls/button/label_button_border.h" |
22 #include "ui/views/controls/button/menu_button.h" | 32 #include "ui/views/controls/button/menu_button.h" |
23 #include "ui/views/controls/button/menu_button_listener.h" | 33 #include "ui/views/controls/button/menu_button_listener.h" |
24 #include "ui/views/controls/combobox/combobox.h" | 34 #include "ui/views/controls/combobox/combobox.h" |
25 #include "ui/views/controls/combobox/combobox_listener.h" | 35 #include "ui/views/controls/combobox/combobox_listener.h" |
26 #include "ui/views/controls/label.h" | 36 #include "ui/views/controls/label.h" |
27 #include "ui/views/controls/menu/menu_runner.h" | 37 #include "ui/views/controls/menu/menu_runner.h" |
28 #include "ui/views/layout/box_layout.h" | 38 #include "ui/views/layout/box_layout.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 int index_; | 91 int index_; |
82 Listener* listener_; | 92 Listener* listener_; |
83 scoped_ptr<PermissionMenuModel> model_; | 93 scoped_ptr<PermissionMenuModel> model_; |
84 scoped_ptr<views::MenuRunner> menu_runner_; | 94 scoped_ptr<views::MenuRunner> menu_runner_; |
85 }; | 95 }; |
86 | 96 |
87 PermissionCombobox::PermissionCombobox(Listener* listener, | 97 PermissionCombobox::PermissionCombobox(Listener* listener, |
88 int index, | 98 int index, |
89 const GURL& url, | 99 const GURL& url, |
90 ContentSetting setting) | 100 ContentSetting setting) |
91 : MenuButton(NULL, base::string16(), this, true), | 101 : MenuButton(nullptr, base::string16(), this, true), |
92 index_(index), | 102 index_(index), |
93 listener_(listener), | 103 listener_(listener), |
94 model_(new PermissionMenuModel( | 104 model_(new PermissionMenuModel( |
95 url, | 105 url, |
96 setting, | 106 setting, |
97 base::Bind(&PermissionCombobox::PermissionChanged, | 107 base::Bind(&PermissionCombobox::PermissionChanged, |
98 base::Unretained(this)))) { | 108 base::Unretained(this)))) { |
99 SetText(model_->GetLabelAt(model_->GetIndexOfCommandId(setting))); | 109 SetText(model_->GetLabelAt(model_->GetIndexOfCommandId(setting))); |
100 SizeToPreferredSize(); | 110 SizeToPreferredSize(); |
101 } | 111 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 index_, permission.setting == CONTENT_SETTING_ALLOW); | 143 index_, permission.setting == CONTENT_SETTING_ALLOW); |
134 } | 144 } |
135 | 145 |
136 /////////////////////////////////////////////////////////////////////////////// | 146 /////////////////////////////////////////////////////////////////////////////// |
137 // View implementation for the permissions bubble. | 147 // View implementation for the permissions bubble. |
138 class PermissionsBubbleDelegateView : public views::BubbleDelegateView, | 148 class PermissionsBubbleDelegateView : public views::BubbleDelegateView, |
139 public views::ButtonListener, | 149 public views::ButtonListener, |
140 public PermissionCombobox::Listener { | 150 public PermissionCombobox::Listener { |
141 public: | 151 public: |
142 PermissionsBubbleDelegateView( | 152 PermissionsBubbleDelegateView( |
143 views::View* anchor, | 153 views::View* anchor_view, |
| 154 views::BubbleBorder::Arrow anchor_arrow, |
144 PermissionBubbleViewViews* owner, | 155 PermissionBubbleViewViews* owner, |
145 const std::string& languages, | 156 const std::string& languages, |
146 const std::vector<PermissionBubbleRequest*>& requests, | 157 const std::vector<PermissionBubbleRequest*>& requests, |
147 const std::vector<bool>& accept_state); | 158 const std::vector<bool>& accept_state); |
148 ~PermissionsBubbleDelegateView() override; | 159 ~PermissionsBubbleDelegateView() override; |
149 | 160 |
150 void Close(); | 161 void Close(); |
151 void SizeToContents(); | 162 void SizeToContents(); |
152 | 163 |
153 // BubbleDelegateView: | 164 // BubbleDelegateView: |
154 bool ShouldShowCloseButton() const override; | 165 bool ShouldShowCloseButton() const override; |
155 bool ShouldShowWindowTitle() const override; | 166 bool ShouldShowWindowTitle() const override; |
156 const gfx::FontList& GetTitleFontList() const override; | 167 const gfx::FontList& GetTitleFontList() const override; |
157 base::string16 GetWindowTitle() const override; | 168 base::string16 GetWindowTitle() const override; |
158 void OnWidgetDestroying(views::Widget* widget) override; | 169 void OnWidgetDestroying(views::Widget* widget) override; |
159 | 170 |
160 // ButtonListener: | 171 // ButtonListener: |
161 void ButtonPressed(views::Button* button, const ui::Event& event) override; | 172 void ButtonPressed(views::Button* button, const ui::Event& event) override; |
162 | 173 |
163 // PermissionCombobox::Listener: | 174 // PermissionCombobox::Listener: |
164 void PermissionSelectionChanged(int index, bool allowed) override; | 175 void PermissionSelectionChanged(int index, bool allowed) override; |
165 | 176 |
| 177 // Updates the anchor's arrow and view. Also repositions the bubble so it's |
| 178 // displayed in the correct location. |
| 179 void UpdateAnchor(views::View* anchor_view, |
| 180 views::BubbleBorder::Arrow anchor_arrow); |
| 181 |
166 private: | 182 private: |
167 PermissionBubbleViewViews* owner_; | 183 PermissionBubbleViewViews* owner_; |
168 views::Button* allow_; | 184 views::Button* allow_; |
169 views::Button* deny_; | 185 views::Button* deny_; |
170 views::Combobox* allow_combobox_; | 186 views::Combobox* allow_combobox_; |
171 base::string16 hostname_; | 187 base::string16 hostname_; |
172 scoped_ptr<PermissionMenuModel> menu_button_model_; | 188 scoped_ptr<PermissionMenuModel> menu_button_model_; |
173 std::vector<PermissionCombobox*> customize_comboboxes_; | 189 std::vector<PermissionCombobox*> customize_comboboxes_; |
174 | 190 |
175 DISALLOW_COPY_AND_ASSIGN(PermissionsBubbleDelegateView); | 191 DISALLOW_COPY_AND_ASSIGN(PermissionsBubbleDelegateView); |
176 }; | 192 }; |
177 | 193 |
178 PermissionsBubbleDelegateView::PermissionsBubbleDelegateView( | 194 PermissionsBubbleDelegateView::PermissionsBubbleDelegateView( |
179 views::View* anchor, | 195 views::View* anchor_view, |
| 196 views::BubbleBorder::Arrow anchor_arrow, |
180 PermissionBubbleViewViews* owner, | 197 PermissionBubbleViewViews* owner, |
181 const std::string& languages, | 198 const std::string& languages, |
182 const std::vector<PermissionBubbleRequest*>& requests, | 199 const std::vector<PermissionBubbleRequest*>& requests, |
183 const std::vector<bool>& accept_state) | 200 const std::vector<bool>& accept_state) |
184 : views::BubbleDelegateView(anchor, views::BubbleBorder::TOP_LEFT), | 201 : views::BubbleDelegateView(anchor_view, anchor_arrow), |
185 owner_(owner), | 202 owner_(owner), |
186 allow_(NULL), | 203 allow_(nullptr), |
187 deny_(NULL), | 204 deny_(nullptr), |
188 allow_combobox_(NULL) { | 205 allow_combobox_(nullptr) { |
189 DCHECK(!requests.empty()); | 206 DCHECK(!requests.empty()); |
190 | 207 |
191 RemoveAllChildViews(true); | 208 RemoveAllChildViews(true); |
192 customize_comboboxes_.clear(); | 209 customize_comboboxes_.clear(); |
193 set_close_on_esc(true); | 210 set_close_on_esc(true); |
194 set_close_on_deactivate(false); | 211 set_close_on_deactivate(false); |
195 | 212 |
196 SetLayoutManager(new views::BoxLayout( | 213 SetLayoutManager(new views::BoxLayout( |
197 views::BoxLayout::kVertical, kBubbleOuterMargin, 0, kItemMajorSpacing)); | 214 views::BoxLayout::kVertical, kBubbleOuterMargin, 0, kItemMajorSpacing)); |
198 | 215 |
199 hostname_ = net::FormatUrl(requests[0]->GetRequestingHostname(), | 216 hostname_ = net::FormatUrl(requests[0]->GetRequestingHostname(), |
200 languages, | 217 languages, |
201 net::kFormatUrlOmitUsernamePassword | | 218 net::kFormatUrlOmitUsernamePassword | |
202 net::kFormatUrlOmitTrailingSlashOnBareHostname, | 219 net::kFormatUrlOmitTrailingSlashOnBareHostname, |
203 net::UnescapeRule::SPACES, NULL, NULL, NULL); | 220 net::UnescapeRule::SPACES, |
| 221 nullptr, nullptr, nullptr); |
204 | 222 |
205 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 223 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
206 for (size_t index = 0; index < requests.size(); index++) { | 224 for (size_t index = 0; index < requests.size(); index++) { |
207 DCHECK(index < accept_state.size()); | 225 DCHECK(index < accept_state.size()); |
208 // The row is laid out containing a leading-aligned label area and a | 226 // The row is laid out containing a leading-aligned label area and a |
209 // trailing column which will be filled if there are multiple permission | 227 // trailing column which will be filled if there are multiple permission |
210 // requests. | 228 // requests. |
211 views::View* row = new views::View(); | 229 views::View* row = new views::View(); |
212 views::GridLayout* row_layout = new views::GridLayout(row); | 230 views::GridLayout* row_layout = new views::GridLayout(row); |
213 row->SetLayoutManager(row_layout); | 231 row->SetLayoutManager(row_layout); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 310 |
293 button_layout->AddPaddingRow(0, kBubbleOuterMargin); | 311 button_layout->AddPaddingRow(0, kBubbleOuterMargin); |
294 } | 312 } |
295 | 313 |
296 PermissionsBubbleDelegateView::~PermissionsBubbleDelegateView() { | 314 PermissionsBubbleDelegateView::~PermissionsBubbleDelegateView() { |
297 if (owner_) | 315 if (owner_) |
298 owner_->Closing(); | 316 owner_->Closing(); |
299 } | 317 } |
300 | 318 |
301 void PermissionsBubbleDelegateView::Close() { | 319 void PermissionsBubbleDelegateView::Close() { |
302 owner_ = NULL; | 320 owner_ = nullptr; |
303 GetWidget()->Close(); | 321 GetWidget()->Close(); |
304 } | 322 } |
305 | 323 |
306 bool PermissionsBubbleDelegateView::ShouldShowCloseButton() const { | 324 bool PermissionsBubbleDelegateView::ShouldShowCloseButton() const { |
307 return true; | 325 return true; |
308 } | 326 } |
309 | 327 |
310 bool PermissionsBubbleDelegateView::ShouldShowWindowTitle() const { | 328 bool PermissionsBubbleDelegateView::ShouldShowWindowTitle() const { |
311 return true; | 329 return true; |
312 } | 330 } |
313 | 331 |
314 const gfx::FontList& PermissionsBubbleDelegateView::GetTitleFontList() const { | 332 const gfx::FontList& PermissionsBubbleDelegateView::GetTitleFontList() const { |
315 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 333 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
316 return rb.GetFontList(ui::ResourceBundle::BaseFont); | 334 return rb.GetFontList(ui::ResourceBundle::BaseFont); |
317 } | 335 } |
318 | 336 |
319 base::string16 PermissionsBubbleDelegateView::GetWindowTitle() const { | 337 base::string16 PermissionsBubbleDelegateView::GetWindowTitle() const { |
320 return l10n_util::GetStringFUTF16(IDS_PERMISSIONS_BUBBLE_PROMPT, | 338 return l10n_util::GetStringFUTF16(IDS_PERMISSIONS_BUBBLE_PROMPT, |
321 hostname_); | 339 hostname_); |
322 } | 340 } |
323 | 341 |
324 void PermissionsBubbleDelegateView::SizeToContents() { | 342 void PermissionsBubbleDelegateView::SizeToContents() { |
325 BubbleDelegateView::SizeToContents(); | 343 BubbleDelegateView::SizeToContents(); |
326 } | 344 } |
327 | 345 |
328 void PermissionsBubbleDelegateView::OnWidgetDestroying(views::Widget* widget) { | 346 void PermissionsBubbleDelegateView::OnWidgetDestroying(views::Widget* widget) { |
329 views::BubbleDelegateView::OnWidgetDestroying(widget); | 347 views::BubbleDelegateView::OnWidgetDestroying(widget); |
330 if (owner_) { | 348 if (owner_) { |
331 owner_->Closing(); | 349 owner_->Closing(); |
332 owner_ = NULL; | 350 owner_ = nullptr; |
333 } | 351 } |
334 } | 352 } |
335 | 353 |
336 void PermissionsBubbleDelegateView::ButtonPressed(views::Button* button, | 354 void PermissionsBubbleDelegateView::ButtonPressed(views::Button* button, |
337 const ui::Event& event) { | 355 const ui::Event& event) { |
338 if (!owner_) | 356 if (!owner_) |
339 return; | 357 return; |
340 | 358 |
341 if (button == allow_) | 359 if (button == allow_) |
342 owner_->Accept(); | 360 owner_->Accept(); |
343 else if (button == deny_) | 361 else if (button == deny_) |
344 owner_->Deny(); | 362 owner_->Deny(); |
345 } | 363 } |
346 | 364 |
347 void PermissionsBubbleDelegateView::PermissionSelectionChanged( | 365 void PermissionsBubbleDelegateView::PermissionSelectionChanged( |
348 int index, bool allowed) { | 366 int index, bool allowed) { |
349 owner_->Toggle(index, allowed); | 367 owner_->Toggle(index, allowed); |
350 } | 368 } |
351 | 369 |
| 370 void PermissionsBubbleDelegateView::UpdateAnchor( |
| 371 views::View* anchor_view, |
| 372 views::BubbleBorder::Arrow anchor_arrow) { |
| 373 if (GetAnchorView() == anchor_view && arrow() == anchor_arrow) |
| 374 return; |
| 375 |
| 376 set_arrow(anchor_arrow); |
| 377 |
| 378 // Update the border in the bubble: will either add or remove the arrow. |
| 379 views::BubbleFrameView* frame = |
| 380 views::BubbleDelegateView::GetBubbleFrameView(); |
| 381 views::BubbleBorder::Arrow adjusted_arrow = anchor_arrow; |
| 382 if (base::i18n::IsRTL()) |
| 383 adjusted_arrow = views::BubbleBorder::horizontal_mirror(adjusted_arrow); |
| 384 frame->SetBubbleBorder(scoped_ptr<views::BubbleBorder>( |
| 385 new views::BubbleBorder(adjusted_arrow, shadow(), color()))); |
| 386 |
| 387 // Reposition the bubble based on the updated arrow and view. |
| 388 SetAnchorView(anchor_view); |
| 389 } |
| 390 |
352 ////////////////////////////////////////////////////////////////////////////// | 391 ////////////////////////////////////////////////////////////////////////////// |
353 // PermissionBubbleViewViews | 392 // PermissionBubbleViewViews |
354 | 393 |
355 PermissionBubbleViewViews::PermissionBubbleViewViews( | 394 PermissionBubbleViewViews::PermissionBubbleViewViews(Browser* browser) |
356 views::View* anchor_view, | 395 : browser_(browser), |
357 const std::string& languages) | 396 delegate_(nullptr), |
358 : anchor_view_(anchor_view), | 397 bubble_delegate_(nullptr) {} |
359 delegate_(NULL), | |
360 bubble_delegate_(NULL), | |
361 languages_(languages) {} | |
362 | 398 |
363 PermissionBubbleViewViews::~PermissionBubbleViewViews() { | 399 PermissionBubbleViewViews::~PermissionBubbleViewViews() { |
364 if (delegate_) | 400 if (delegate_) |
365 delegate_->SetView(NULL); | 401 delegate_->SetView(nullptr); |
| 402 } |
| 403 |
| 404 views::View* PermissionBubbleViewViews::GetAnchorView() { |
| 405 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_); |
| 406 |
| 407 if (browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) |
| 408 return browser_view->GetLocationBarView()->location_icon_view(); |
| 409 |
| 410 if (browser_view->IsFullscreenBubbleVisible()) |
| 411 return browser_view->exclusive_access_bubble()->GetView(); |
| 412 |
| 413 return browser_view->top_container(); |
| 414 } |
| 415 |
| 416 views::BubbleBorder::Arrow PermissionBubbleViewViews::GetAnchorArrow() { |
| 417 if (browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) |
| 418 return views::BubbleBorder::TOP_LEFT; |
| 419 return views::BubbleBorder::NONE; |
| 420 } |
| 421 |
| 422 void PermissionBubbleViewViews::UpdateAnchorPosition() { |
| 423 if (IsVisible()) |
| 424 bubble_delegate_->UpdateAnchor(GetAnchorView(), GetAnchorArrow()); |
366 } | 425 } |
367 | 426 |
368 void PermissionBubbleViewViews::SetDelegate(Delegate* delegate) { | 427 void PermissionBubbleViewViews::SetDelegate(Delegate* delegate) { |
369 delegate_ = delegate; | 428 delegate_ = delegate; |
370 } | 429 } |
371 | 430 |
372 void PermissionBubbleViewViews::Show( | 431 void PermissionBubbleViewViews::Show( |
373 const std::vector<PermissionBubbleRequest*>& requests, | 432 const std::vector<PermissionBubbleRequest*>& requests, |
374 const std::vector<bool>& values) { | 433 const std::vector<bool>& values) { |
375 if (bubble_delegate_ != NULL) | 434 if (bubble_delegate_) |
376 bubble_delegate_->Close(); | 435 bubble_delegate_->Close(); |
377 | 436 |
378 bubble_delegate_ = | 437 bubble_delegate_ = |
379 new PermissionsBubbleDelegateView(anchor_view_, this, languages_, | 438 new PermissionsBubbleDelegateView( |
380 requests, values); | 439 GetAnchorView(), GetAnchorArrow(), this, |
| 440 browser_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages), |
| 441 requests, values); |
| 442 |
| 443 // Set |parent_window| because some valid anchors can become hidden. |
| 444 bubble_delegate_->set_parent_window(browser_->window()->GetNativeWindow()); |
| 445 |
381 views::BubbleDelegateView::CreateBubble(bubble_delegate_)->Show(); | 446 views::BubbleDelegateView::CreateBubble(bubble_delegate_)->Show(); |
382 bubble_delegate_->SizeToContents(); | 447 bubble_delegate_->SizeToContents(); |
383 } | 448 } |
384 | 449 |
385 bool PermissionBubbleViewViews::CanAcceptRequestUpdate() { | 450 bool PermissionBubbleViewViews::CanAcceptRequestUpdate() { |
386 return !(bubble_delegate_ && bubble_delegate_->IsMouseHovered()); | 451 return !(bubble_delegate_ && bubble_delegate_->IsMouseHovered()); |
387 } | 452 } |
388 | 453 |
389 void PermissionBubbleViewViews::Hide() { | 454 void PermissionBubbleViewViews::Hide() { |
390 if (bubble_delegate_) { | 455 if (bubble_delegate_) { |
391 bubble_delegate_->Close(); | 456 bubble_delegate_->Close(); |
392 bubble_delegate_ = NULL; | 457 bubble_delegate_ = nullptr; |
393 } | 458 } |
394 } | 459 } |
395 | 460 |
396 bool PermissionBubbleViewViews::IsVisible() { | 461 bool PermissionBubbleViewViews::IsVisible() { |
397 return bubble_delegate_ != NULL; | 462 return bubble_delegate_ != nullptr; |
398 } | 463 } |
399 | 464 |
400 void PermissionBubbleViewViews::Closing() { | 465 void PermissionBubbleViewViews::Closing() { |
401 if (bubble_delegate_) | 466 if (bubble_delegate_) |
402 bubble_delegate_ = NULL; | 467 bubble_delegate_ = nullptr; |
403 if (delegate_) | 468 if (delegate_) |
404 delegate_->Closing(); | 469 delegate_->Closing(); |
405 } | 470 } |
406 | 471 |
407 void PermissionBubbleViewViews::Toggle(int index, bool value) { | 472 void PermissionBubbleViewViews::Toggle(int index, bool value) { |
408 if (delegate_) | 473 if (delegate_) |
409 delegate_->ToggleAccept(index, value); | 474 delegate_->ToggleAccept(index, value); |
410 } | 475 } |
411 | 476 |
412 void PermissionBubbleViewViews::Accept() { | 477 void PermissionBubbleViewViews::Accept() { |
413 if (delegate_) | 478 if (delegate_) |
414 delegate_->Accept(); | 479 delegate_->Accept(); |
415 } | 480 } |
416 | 481 |
417 void PermissionBubbleViewViews::Deny() { | 482 void PermissionBubbleViewViews::Deny() { |
418 if (delegate_) | 483 if (delegate_) |
419 delegate_->Deny(); | 484 delegate_->Deny(); |
420 } | 485 } |
OLD | NEW |