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 #ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_ 6 #define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_ 7 8 #include "base/callback.h" 9 #include "base/compiler_specific.h" 10 #include "base/macros.h" 11 #include "base/scoped_observer.h" 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" 13 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" 14 #include "chrome/browser/ui/views/extensions/extension_view_views.h" 15 #include "content/public/browser/devtools_agent_host_observer.h" 16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "extensions/browser/extension_registry.h" 19 #include "extensions/browser/extension_registry_observer.h" 20 #include "ui/views/bubble/bubble_dialog_delegate_view.h" 21 #include "url/gurl.h" 22 23 #if defined(USE_AURA) 24 #include "ui/wm/public/activation_change_observer.h" 25 #endif 26 27 class ExtensionViewViews; 28 29 namespace content { 30 class BrowserContext; 31 class DevToolsAgentHost; 32 } 33 34 namespace extensions { 35 class Extension; 36 class ExtensionViewHost; 37 enum class UnloadedExtensionReason; 38 } 39 40 // The bubble used for hosting a browser-action popup provided by an extension. 41 class ExtensionPopup : public views::BubbleDialogDelegateView, 42 #if defined(USE_AURA) 43 public wm::ActivationChangeObserver, 44 #endif 45 public ExtensionViewViews::Container, 46 public extensions::ExtensionRegistryObserver, 47 public content::NotificationObserver, 48 public TabStripModelObserver, 49 public content::DevToolsAgentHostObserver { 50 public: 51 enum ShowAction { 52 SHOW, 53 SHOW_AND_INSPECT, 54 }; 55 56 // The min/max height of popups. 57 // The minimum is just a little larger than the size of the button itself. 58 // The maximum is an arbitrary number and should be smaller than most screens. 59 static constexpr gfx::Size kMinSize = {25, 25}; 60 static constexpr gfx::Size kMaxSize = {800, 600}; 61 62 // Creates and shows a popup with the given |host| positioned adjacent to 63 // |anchor_view|. 64 // The positioning of the pop-up is determined by |arrow| according to the 65 // following logic: The popup is anchored so that the corner indicated by the 66 // value of |arrow| remains fixed during popup resizes. If |arrow| is 67 // BOTTOM_*, then the popup 'pops up', otherwise the popup 'drops down'. 68 // The actual display of the popup is delayed until the page contents 69 // finish loading in order to minimize UI flashing and resizing. 70 static void ShowPopup(std::unique_ptr<extensions::ExtensionViewHost> host, 71 views::View* anchor_view, 72 views::BubbleBorder::Arrow arrow, 73 ShowAction show_action); 74 75 ~ExtensionPopup() override; 76 host()77 extensions::ExtensionViewHost* host() const { return host_.get(); } 78 79 // views::BubbleDialogDelegateView: 80 gfx::Size CalculatePreferredSize() const override; 81 void AddedToWidget() override; 82 void OnWidgetActivationChanged(views::Widget* widget, bool active) override; 83 #if defined(USE_AURA) 84 void OnWidgetDestroying(views::Widget* widget) override; 85 86 // wm::ActivationChangeObserver: 87 void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, 88 aura::Window* gained_active, 89 aura::Window* lost_active) override; 90 #endif 91 92 // ExtensionViewViews::Container: 93 void OnExtensionSizeChanged(ExtensionViewViews* view) override; 94 gfx::Size GetMinBounds() override; 95 gfx::Size GetMaxBounds() override; 96 97 // extensions::ExtensionRegistryObserver: 98 void OnExtensionUnloaded(content::BrowserContext* browser_context, 99 const extensions::Extension* extension, 100 extensions::UnloadedExtensionReason reason) override; 101 102 // content::NotificationObserver: 103 void Observe(int type, 104 const content::NotificationSource& source, 105 const content::NotificationDetails& details) override; 106 107 // TabStripModelObserver: 108 void OnTabStripModelChanged( 109 TabStripModel* tab_strip_model, 110 const TabStripModelChange& change, 111 const TabStripSelectionChange& selection) override; 112 113 // content::DevToolsAgentHostObserver: 114 void DevToolsAgentHostAttached( 115 content::DevToolsAgentHost* agent_host) override; 116 void DevToolsAgentHostDetached( 117 content::DevToolsAgentHost* agent_host) override; 118 119 private: 120 ExtensionPopup(std::unique_ptr<extensions::ExtensionViewHost> host, 121 views::View* anchor_view, 122 views::BubbleBorder::Arrow arrow, 123 ShowAction show_action); 124 125 // Shows the bubble, focuses its content, and registers listeners. 126 void ShowBubble(); 127 128 // Closes the bubble if the devtools window is not attached. 129 void CloseUnlessUnderInspection(); 130 131 // The contained host for the view. 132 std::unique_ptr<extensions::ExtensionViewHost> host_; 133 134 ExtensionViewViews* extension_view_; 135 136 ScopedObserver<extensions::ExtensionRegistry, 137 extensions::ExtensionRegistryObserver> 138 extension_registry_observer_; 139 140 ShowAction show_action_; 141 142 content::NotificationRegistrar registrar_; 143 144 DISALLOW_COPY_AND_ASSIGN(ExtensionPopup); 145 }; 146 147 #endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_ 148