| Index: chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
|
| diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
|
| index f56d0e88c901fa9f36b5d09d240ff3103bb3accc..ded5a144902386b2b05f4b673d19f81fd89d9efe 100644
|
| --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
|
| +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
|
| @@ -2,8 +2,6 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "chrome/browser/ui/views/extensions/extension_installed_bubble_view.h"
|
| -
|
| #include <algorithm>
|
| #include <string>
|
|
|
| @@ -15,9 +13,12 @@
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_window.h"
|
| #include "chrome/browser/ui/chrome_pages.h"
|
| +#include "chrome/browser/ui/extensions/extension_installed_bubble.h"
|
| #include "chrome/browser/ui/singleton_tabs.h"
|
| +#include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h"
|
| #include "chrome/browser/ui/views/frame/browser_view.h"
|
| #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
|
| +#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
|
| #include "chrome/browser/ui/views/location_bar/page_action_with_badge_view.h"
|
| #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h"
|
| #include "chrome/browser/ui/views/toolbar/app_menu_button.h"
|
| @@ -35,14 +36,15 @@
|
| #include "ui/gfx/render_text.h"
|
| #include "ui/gfx/text_elider.h"
|
| #include "ui/resources/grit/ui_resources.h"
|
| +#include "ui/views/bubble/bubble_dialog_delegate.h"
|
| #include "ui/views/bubble/bubble_frame_view.h"
|
| +#include "ui/views/controls/button/button.h"
|
| #include "ui/views/controls/button/image_button.h"
|
| #include "ui/views/controls/image_view.h"
|
| #include "ui/views/controls/label.h"
|
| #include "ui/views/controls/link.h"
|
| #include "ui/views/controls/link_listener.h"
|
| #include "ui/views/layout/box_layout.h"
|
| -#include "ui/views/layout/fill_layout.h"
|
| #include "ui/views/layout/grid_layout.h"
|
| #include "ui/views/layout/layout_constants.h"
|
|
|
| @@ -111,34 +113,83 @@ class HeadingAndCloseButtonView : public views::View {
|
| DISALLOW_COPY_AND_ASSIGN(HeadingAndCloseButtonView);
|
| };
|
|
|
| -} // namespace
|
| +// Provides feedback to the user upon successful installation of an
|
| +// extension. Depending on the type of extension, the Bubble will
|
| +// point to:
|
| +// OMNIBOX_KEYWORD-> The omnibox.
|
| +// BROWSER_ACTION -> The browserAction icon in the toolbar.
|
| +// PAGE_ACTION -> A preview of the pageAction icon in the location
|
| +// bar which is shown while the Bubble is shown.
|
| +// GENERIC -> The app menu. This case includes pageActions that don't
|
| +// specify a default icon.
|
| +class ExtensionInstalledBubbleView : public BubbleSyncPromoDelegate,
|
| + public views::BubbleDialogDelegateView,
|
| + public views::ButtonListener,
|
| + public views::LinkListener {
|
| + public:
|
| + explicit ExtensionInstalledBubbleView(ExtensionInstalledBubble* bubble);
|
| + ~ExtensionInstalledBubbleView() override;
|
| +
|
| + // Recalculate the anchor position for this bubble.
|
| + void UpdateAnchorView();
|
| +
|
| + void CloseBubble();
|
| +
|
| + private:
|
| + Browser* browser() { return controller_->browser(); }
|
| +
|
| + // views::BubbleDialogDelegateView:
|
| + void Init() override;
|
| + View* CreateFootnoteView() override;
|
| + int GetDialogButtons() const override;
|
| +
|
| + // BubbleSyncPromoDelegate:
|
| + void OnSignInLinkClicked() override;
|
| +
|
| + // views::LinkListener:
|
| + void LinkClicked(views::Link* source, int event_flags) override;
|
| +
|
| + // views::ButtonListener:
|
| + void ButtonPressed(views::Button* sender, const ui::Event& event) override;
|
| +
|
| + ExtensionInstalledBubble* controller_;
|
| + ExtensionInstalledBubble::BubbleType type_;
|
| + ExtensionInstalledBubble::AnchorPosition anchor_position_;
|
| +
|
| + // The button to close the bubble.
|
| + views::LabelButton* close_;
|
| +
|
| + // The shortcut to open the manage shortcuts page.
|
| + views::Link* manage_shortcut_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ExtensionInstalledBubbleView);
|
| +};
|
|
|
| ExtensionInstalledBubbleView::ExtensionInstalledBubbleView(
|
| - ExtensionInstalledBubble* bubble,
|
| - BubbleReference bubble_reference)
|
| - : bubble_(bubble),
|
| - bubble_reference_(bubble_reference),
|
| - extension_(bubble->extension()),
|
| - browser_(bubble->browser()),
|
| - type_(bubble->type()),
|
| - anchor_position_(bubble->anchor_position()),
|
| + ExtensionInstalledBubble* controller)
|
| + : BubbleDialogDelegateView(nullptr,
|
| + controller->anchor_position() ==
|
| + ExtensionInstalledBubble::ANCHOR_OMNIBOX
|
| + ? views::BubbleBorder::TOP_LEFT
|
| + : views::BubbleBorder::TOP_RIGHT),
|
| + controller_(controller),
|
| close_(nullptr),
|
| manage_shortcut_(nullptr) {}
|
|
|
| ExtensionInstalledBubbleView::~ExtensionInstalledBubbleView() {}
|
|
|
| void ExtensionInstalledBubbleView::UpdateAnchorView() {
|
| - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
|
| + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
|
|
|
| views::View* reference_view = nullptr;
|
| - switch (anchor_position_) {
|
| + switch (controller_->anchor_position()) {
|
| case ExtensionInstalledBubble::ANCHOR_BROWSER_ACTION: {
|
| BrowserActionsContainer* container =
|
| browser_view->GetToolbarView()->browser_actions();
|
| // Hitting this DCHECK means |ShouldShow| failed.
|
| DCHECK(!container->animating());
|
|
|
| - reference_view = container->GetViewForId(extension_->id());
|
| + reference_view = container->GetViewForId(controller_->extension()->id());
|
| // If the view is not visible then it is in the chevron, so point the
|
| // install bubble to the chevron instead. If this is an incognito window,
|
| // both could be invisible.
|
| @@ -152,8 +203,8 @@ void ExtensionInstalledBubbleView::UpdateAnchorView() {
|
| case ExtensionInstalledBubble::ANCHOR_PAGE_ACTION: {
|
| LocationBarView* location_bar_view = browser_view->GetLocationBarView();
|
| ExtensionAction* page_action =
|
| - extensions::ExtensionActionManager::Get(browser_->profile())
|
| - ->GetPageAction(*extension_);
|
| + extensions::ExtensionActionManager::Get(browser()->profile())
|
| + ->GetPageAction(*controller_->extension());
|
| location_bar_view->SetPreviewEnabledPageAction(page_action,
|
| true); // preview_enabled
|
| reference_view = location_bar_view->GetPageActionView(page_action);
|
| @@ -161,9 +212,7 @@ void ExtensionInstalledBubbleView::UpdateAnchorView() {
|
| break;
|
| }
|
| case ExtensionInstalledBubble::ANCHOR_OMNIBOX: {
|
| - LocationBarView* location_bar_view = browser_view->GetLocationBarView();
|
| - reference_view = location_bar_view;
|
| - DCHECK(reference_view);
|
| + reference_view = browser_view->GetLocationBarView()->location_icon_view();
|
| break;
|
| }
|
| case ExtensionInstalledBubble::ANCHOR_APP_MENU:
|
| @@ -177,89 +226,61 @@ void ExtensionInstalledBubbleView::UpdateAnchorView() {
|
| SetAnchorView(reference_view);
|
| }
|
|
|
| -views::View* ExtensionInstalledBubbleView::CreateFootnoteView() {
|
| - if (!(bubble_->options() & ExtensionInstalledBubble::SIGN_IN_PROMO))
|
| - return nullptr;
|
| -
|
| - return new BubbleSyncPromoView(this,
|
| - IDS_EXTENSION_INSTALLED_SYNC_PROMO_LINK_NEW,
|
| - IDS_EXTENSION_INSTALLED_SYNC_PROMO_NEW);
|
| -}
|
| -
|
| -void ExtensionInstalledBubbleView::WindowClosing() {
|
| - if (anchor_position_ == ExtensionInstalledBubble::ANCHOR_PAGE_ACTION) {
|
| - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
|
| +void ExtensionInstalledBubbleView::CloseBubble() {
|
| + if (controller_ && controller_->anchor_position() ==
|
| + ExtensionInstalledBubble::ANCHOR_PAGE_ACTION) {
|
| + BrowserView* browser_view =
|
| + BrowserView::GetBrowserViewForBrowser(browser());
|
| browser_view->GetLocationBarView()->SetPreviewEnabledPageAction(
|
| - extensions::ExtensionActionManager::Get(browser_->profile())
|
| - ->GetPageAction(*extension_),
|
| + extensions::ExtensionActionManager::Get(browser()->profile())
|
| + ->GetPageAction(*controller_->extension()),
|
| false); // preview_enabled
|
| }
|
| + controller_ = nullptr;
|
| + GetWidget()->Close();
|
| }
|
|
|
| -gfx::Rect ExtensionInstalledBubbleView::GetAnchorRect() const {
|
| - // For omnibox keyword bubbles, move the arrow to point to the left edge
|
| - // of the omnibox, just to the right of the icon.
|
| - if (type_ == ExtensionInstalledBubble::OMNIBOX_KEYWORD) {
|
| - const LocationBarView* location_bar_view =
|
| - BrowserView::GetBrowserViewForBrowser(browser_)->GetLocationBarView();
|
| - return gfx::Rect(location_bar_view->GetOmniboxViewOrigin(),
|
| - gfx::Size(0, location_bar_view->omnibox_view()->height()));
|
| - }
|
| - return views::BubbleDelegateView::GetAnchorRect();
|
| -}
|
| -
|
| -void ExtensionInstalledBubbleView::OnWidgetClosing(views::Widget* widget) {
|
| - if (bubble_reference_) {
|
| - DCHECK_EQ(widget, GetWidget());
|
| - // A more specific close reason should already be recorded.
|
| - // This is the catch-all close reason for this bubble.
|
| - bubble_reference_->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST);
|
| - }
|
| -}
|
| +views::View* ExtensionInstalledBubbleView::CreateFootnoteView() {
|
| + if (!(controller_->options() & ExtensionInstalledBubble::SIGN_IN_PROMO))
|
| + return nullptr;
|
|
|
| -void ExtensionInstalledBubbleView::OnWidgetActivationChanged(
|
| - views::Widget* widget,
|
| - bool active) {
|
| - if (!active && bubble_reference_ && widget == GetWidget())
|
| - bubble_reference_->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST);
|
| + return new BubbleSyncPromoView(this,
|
| + IDS_EXTENSION_INSTALLED_SYNC_PROMO_LINK_NEW,
|
| + IDS_EXTENSION_INSTALLED_SYNC_PROMO_NEW);
|
| }
|
|
|
| -bool ExtensionInstalledBubbleView::AcceleratorPressed(
|
| - const ui::Accelerator& accelerator) {
|
| - if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
|
| - return false;
|
| - DCHECK(bubble_reference_);
|
| - bool did_close = bubble_reference_->CloseBubble(BUBBLE_CLOSE_USER_DISMISSED);
|
| - DCHECK(did_close);
|
| - return true;
|
| +int ExtensionInstalledBubbleView::GetDialogButtons() const {
|
| + return ui::DIALOG_BUTTON_NONE;
|
| }
|
|
|
| void ExtensionInstalledBubbleView::OnSignInLinkClicked() {
|
| - GetWidget()->Close();
|
| chrome::ShowBrowserSignin(
|
| - browser_,
|
| + browser(),
|
| signin_metrics::AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE);
|
| + CloseBubble();
|
| }
|
|
|
| void ExtensionInstalledBubbleView::ButtonPressed(views::Button* sender,
|
| const ui::Event& event) {
|
| DCHECK_EQ(sender, close_);
|
| - GetWidget()->Close();
|
| + CloseBubble();
|
| }
|
|
|
| void ExtensionInstalledBubbleView::LinkClicked(views::Link* source,
|
| int event_flags) {
|
| DCHECK_EQ(manage_shortcut_, source);
|
| - GetWidget()->Close();
|
| + CloseBubble();
|
|
|
| std::string configure_url = chrome::kChromeUIExtensionsURL;
|
| configure_url += chrome::kExtensionConfigureCommandsSubPage;
|
| chrome::NavigateParams params(
|
| - chrome::GetSingletonTabNavigateParams(browser_, GURL(configure_url)));
|
| + chrome::GetSingletonTabNavigateParams(browser(), GURL(configure_url)));
|
| chrome::Navigate(¶ms);
|
| }
|
|
|
| -void ExtensionInstalledBubbleView::InitLayout() {
|
| +void ExtensionInstalledBubbleView::Init() {
|
| + UpdateAnchorView();
|
| +
|
| // The Extension Installed bubble takes on various forms, depending on the
|
| // type of extension installed. In general, though, they are all similar:
|
| //
|
| @@ -277,14 +298,13 @@ void ExtensionInstalledBubbleView::InitLayout() {
|
| // or a link to configure the keybinding shortcut (if one exists).
|
| // Extra info can include a promo for signing into sync.
|
|
|
| - const ExtensionInstalledBubble& bubble = *bubble_;
|
| // The number of rows in the content section of the bubble.
|
| int main_content_row_count = 1;
|
| - if (bubble.options() & ExtensionInstalledBubble::HOW_TO_USE)
|
| + if (controller_->options() & ExtensionInstalledBubble::HOW_TO_USE)
|
| ++main_content_row_count;
|
| - if (bubble.options() & ExtensionInstalledBubble::SHOW_KEYBINDING)
|
| + if (controller_->options() & ExtensionInstalledBubble::SHOW_KEYBINDING)
|
| ++main_content_row_count;
|
| - if (bubble.options() & ExtensionInstalledBubble::HOW_TO_MANAGE)
|
| + if (controller_->options() & ExtensionInstalledBubble::HOW_TO_MANAGE)
|
| ++main_content_row_count;
|
|
|
| views::GridLayout* layout = new views::GridLayout(this);
|
| @@ -304,7 +324,7 @@ void ExtensionInstalledBubbleView::InitLayout() {
|
| ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
| const gfx::FontList& font_list = rb.GetFontList(ui::ResourceBundle::BaseFont);
|
|
|
| - const SkBitmap& bitmap = bubble.icon();
|
| + const SkBitmap& bitmap = controller_->icon();
|
| // Add the icon (for all options).
|
| // Scale down to 43x43, but allow smaller icons (don't scale up).
|
| gfx::Size size(bitmap.width(), bitmap.height());
|
| @@ -318,7 +338,8 @@ void ExtensionInstalledBubbleView::InitLayout() {
|
| layout->AddView(icon, 1, main_content_row_count);
|
|
|
| // Add the heading (for all options).
|
| - base::string16 extension_name = base::UTF8ToUTF16(extension_->name());
|
| + base::string16 extension_name =
|
| + base::UTF8ToUTF16(controller_->extension()->name());
|
| base::i18n::AdjustStringForLocaleDirection(&extension_name);
|
| views::Label* heading =
|
| CreateLabel(l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALLED_HEADING,
|
| @@ -341,11 +362,12 @@ void ExtensionInstalledBubbleView::InitLayout() {
|
| layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
|
| };
|
|
|
| - if (bubble.options() & ExtensionInstalledBubble::HOW_TO_USE) {
|
| - add_content_view(CreateLabel(bubble.GetHowToUseDescription(), font_list));
|
| + if (controller_->options() & ExtensionInstalledBubble::HOW_TO_USE) {
|
| + add_content_view(
|
| + CreateLabel(controller_->GetHowToUseDescription(), font_list));
|
| }
|
|
|
| - if (bubble.options() & ExtensionInstalledBubble::SHOW_KEYBINDING) {
|
| + if (controller_->options() & ExtensionInstalledBubble::SHOW_KEYBINDING) {
|
| manage_shortcut_ = new views::Link(
|
| l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALLED_MANAGE_SHORTCUTS));
|
| manage_shortcut_->set_listener(this);
|
| @@ -353,79 +375,86 @@ void ExtensionInstalledBubbleView::InitLayout() {
|
| add_content_view(manage_shortcut_);
|
| }
|
|
|
| - if (bubble.options() & ExtensionInstalledBubble::HOW_TO_MANAGE) {
|
| + if (controller_->options() & ExtensionInstalledBubble::HOW_TO_MANAGE) {
|
| add_content_view(CreateLabel(
|
| l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALLED_MANAGE_INFO),
|
| font_list));
|
| }
|
| }
|
|
|
| -// Views specific implementation.
|
| -bool ExtensionInstalledBubble::ShouldShow() {
|
| - if (anchor_position() == ANCHOR_BROWSER_ACTION) {
|
| - BrowserActionsContainer* container =
|
| - BrowserView::GetBrowserViewForBrowser(browser())
|
| - ->GetToolbarView()
|
| - ->browser_actions();
|
| - return !container->animating();
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -class ExtensionInstalledBubbleUi : public BubbleUi {
|
| +// NB: This bubble is using the temporarily-deprecated bubble manager interface
|
| +// BubbleUi. Do not copy this pattern.
|
| +class ExtensionInstalledBubbleUi : public BubbleUi,
|
| + public views::WidgetObserver {
|
| public:
|
| explicit ExtensionInstalledBubbleUi(ExtensionInstalledBubble* bubble);
|
| ~ExtensionInstalledBubbleUi() override;
|
|
|
| - private:
|
| // BubbleUi:
|
| void Show(BubbleReference bubble_reference) override;
|
| void Close() override;
|
| void UpdateAnchorPosition() override;
|
|
|
| + // WidgetObserver:
|
| + void OnWidgetClosing(views::Widget* widget) override;
|
| +
|
| + private:
|
| ExtensionInstalledBubble* bubble_;
|
| - ExtensionInstalledBubbleView* delegate_view_;
|
| + ExtensionInstalledBubbleView* bubble_view_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ExtensionInstalledBubbleUi);
|
| };
|
|
|
| -// Implemented here to create the platform specific instance of the BubbleUi.
|
| -std::unique_ptr<BubbleUi> ExtensionInstalledBubble::BuildBubbleUi() {
|
| - return base::WrapUnique(new ExtensionInstalledBubbleUi(this));
|
| -}
|
| -
|
| ExtensionInstalledBubbleUi::ExtensionInstalledBubbleUi(
|
| ExtensionInstalledBubble* bubble)
|
| - : bubble_(bubble), delegate_view_(nullptr) {
|
| + : bubble_(bubble), bubble_view_(nullptr) {
|
| DCHECK(bubble_);
|
| }
|
|
|
| -ExtensionInstalledBubbleUi::~ExtensionInstalledBubbleUi() {}
|
| -
|
| -void ExtensionInstalledBubbleUi::Show(BubbleReference bubble_reference) {
|
| - // Owned by widget.
|
| - delegate_view_ = new ExtensionInstalledBubbleView(bubble_, bubble_reference);
|
| - delegate_view_->UpdateAnchorView();
|
| -
|
| - delegate_view_->set_arrow(bubble_->type() == bubble_->OMNIBOX_KEYWORD
|
| - ? views::BubbleBorder::TOP_LEFT
|
| - : views::BubbleBorder::TOP_RIGHT);
|
| +ExtensionInstalledBubbleUi::~ExtensionInstalledBubbleUi() {
|
| + if (bubble_view_)
|
| + bubble_view_->GetWidget()->RemoveObserver(this);
|
| +}
|
|
|
| - delegate_view_->InitLayout();
|
| +void ExtensionInstalledBubbleUi::Show(BubbleReference /*bubble_reference*/) {
|
| + bubble_view_ = new ExtensionInstalledBubbleView(bubble_);
|
|
|
| - views::BubbleDelegateView::CreateBubble(delegate_view_)->Show();
|
| + views::BubbleDialogDelegateView::CreateBubble(bubble_view_)->Show();
|
| + bubble_view_->GetWidget()->AddObserver(this);
|
| content::RecordAction(
|
| base::UserMetricsAction("Signin_Impression_FromExtensionInstallBubble"));
|
| }
|
|
|
| void ExtensionInstalledBubbleUi::Close() {
|
| - if (delegate_view_) {
|
| - delegate_view_->GetWidget()->Close();
|
| - delegate_view_ = nullptr;
|
| - }
|
| + if (bubble_view_)
|
| + bubble_view_->CloseBubble();
|
| }
|
|
|
| void ExtensionInstalledBubbleUi::UpdateAnchorPosition() {
|
| - DCHECK(delegate_view_);
|
| - delegate_view_->UpdateAnchorView();
|
| + DCHECK(bubble_view_);
|
| + bubble_view_->UpdateAnchorView();
|
| +}
|
| +
|
| +void ExtensionInstalledBubbleUi::OnWidgetClosing(views::Widget* widget) {
|
| + widget->RemoveObserver(this);
|
| + bubble_view_ = nullptr;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Views specific implementation.
|
| +bool ExtensionInstalledBubble::ShouldShow() {
|
| + if (anchor_position() == ANCHOR_BROWSER_ACTION) {
|
| + BrowserActionsContainer* container =
|
| + BrowserView::GetBrowserViewForBrowser(browser())
|
| + ->GetToolbarView()
|
| + ->browser_actions();
|
| + return !container->animating();
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// Implemented here to create the platform specific instance of the BubbleUi.
|
| +std::unique_ptr<BubbleUi> ExtensionInstalledBubble::BuildBubbleUi() {
|
| + return base::WrapUnique(new ExtensionInstalledBubbleUi(this));
|
| }
|
|
|