summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authortwiz@google.com <twiz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-10 01:59:11 +0000
committertwiz@google.com <twiz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-10 01:59:11 +0000
commita95631cb9427e4d20c243dcd0f36da3fd3e7cb55 (patch)
tree09da2c4493a7303671961051b32718830c451ad7 /chrome/browser
parent2007ad49132097b2a2eb10d0025361d1bf7a9340 (diff)
downloadchromium_src-a95631cb9427e4d20c243dcd0f36da3fd3e7cb55.zip
chromium_src-a95631cb9427e4d20c243dcd0f36da3fd3e7cb55.tar.gz
chromium_src-a95631cb9427e4d20c243dcd0f36da3fd3e7cb55.tar.bz2
A collection of fixes allowing the chrome.experimental.popup.* set of APIs to function in circumstances where there is no Browser instance present. This is a symptom of a tab-contents view hosted in an ExternalTabContainer.The major change here is the removal of the explicit dependency on a Browser instance across all of the delegates involved when showing a pop-up API. I modified the following delegates:- ExtensionPopupHost::Delegate- TabContentsDelegate- ExtensionFunctionDispatcher::DelegateBecause the pop-up requires a Profile, and a gfx::NativeWindow, I added methods to the above interfaces to provide them.BUG=noneTEST=ExtensionApiTest.FLAKY_Popup
Review URL: http://codereview.chromium.org/434046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34219 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser.h1
-rw-r--r--chrome/browser/dom_ui/dom_ui.h2
-rw-r--r--chrome/browser/extensions/extension_dom_ui.cc27
-rw-r--r--chrome/browser/extensions/extension_dom_ui.h4
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc20
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h14
-rw-r--r--chrome/browser/extensions/extension_host.cc17
-rw-r--r--chrome/browser/extensions/extension_host.h7
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc8
-rw-r--r--chrome/browser/extensions/extension_popup_apitest.cc1
-rw-r--r--chrome/browser/extensions/extension_popup_host.cc31
-rw-r--r--chrome/browser/extensions/extension_popup_host.h8
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc7
-rw-r--r--chrome/browser/external_tab_container.cc9
-rw-r--r--chrome/browser/external_tab_container.h6
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h7
-rw-r--r--chrome/browser/views/browser_actions_container.cc7
-rw-r--r--chrome/browser/views/browser_bubble.cc30
-rw-r--r--chrome/browser/views/extensions/extension_popup.cc30
-rw-r--r--chrome/browser/views/extensions/extension_popup.h14
-rw-r--r--chrome/browser/views/location_bar_view.cc5
21 files changed, 215 insertions, 40 deletions
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index fd7c63d..5192bf0 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -575,6 +575,7 @@ class Browser : public TabStripModelDelegate,
virtual bool ShouldAddNavigationsToHistory() const;
virtual void OnDidGetApplicationInfo(TabContents* tab_contents,
int32 page_id);
+ virtual Browser* GetBrowser() { return this; }
// Overridden from SelectFileDialog::Listener:
virtual void FileSelected(const FilePath& path, int index, void* params);
diff --git a/chrome/browser/dom_ui/dom_ui.h b/chrome/browser/dom_ui/dom_ui.h
index ad4c2dc..2156b30 100644
--- a/chrome/browser/dom_ui/dom_ui.h
+++ b/chrome/browser/dom_ui/dom_ui.h
@@ -111,7 +111,7 @@ class DOMUI {
ThemeProvider* GetThemeProvider() const;
- TabContents* tab_contents() { return tab_contents_; }
+ TabContents* tab_contents() const { return tab_contents_; }
Profile* GetProfile();
diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc
index fb95005..e9f1996 100644
--- a/chrome/browser/extensions/extension_dom_ui.cc
+++ b/chrome/browser/extensions/extension_dom_ui.cc
@@ -63,8 +63,31 @@ void ExtensionDOMUI::ProcessDOMUIMessage(const std::string& message,
has_callback);
}
-Browser* ExtensionDOMUI::GetBrowser() {
- return static_cast<Browser*>(tab_contents()->delegate());
+Browser* ExtensionDOMUI::GetBrowser() const {
+ TabContentsDelegate* tab_contents_delegate = tab_contents()->delegate();
+ if (tab_contents_delegate)
+ return tab_contents_delegate->GetBrowser();
+ return NULL;
+}
+
+Profile* ExtensionDOMUI::GetProfile() {
+ return DOMUI::GetProfile();
+}
+
+gfx::NativeWindow ExtensionDOMUI::GetFrameNativeWindow() {
+ gfx::NativeWindow native_window =
+ ExtensionFunctionDispatcher::Delegate::GetFrameNativeWindow();
+
+ // If there was no window associated with the function dispatcher delegate,
+ // then this DOMUI may be hosted in an ExternalTabContainer, and a framing
+ // window will be accessible through the tab_contents.
+ if (!native_window) {
+ TabContentsDelegate* tab_contents_delegate = tab_contents()->delegate();
+ if (tab_contents_delegate)
+ native_window = tab_contents_delegate->GetFrameNativeWindow();
+ }
+
+ return native_window;
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/extensions/extension_dom_ui.h b/chrome/browser/extensions/extension_dom_ui.h
index 0a53607..bd7a0ac 100644
--- a/chrome/browser/extensions/extension_dom_ui.h
+++ b/chrome/browser/extensions/extension_dom_ui.h
@@ -40,11 +40,13 @@ class ExtensionDOMUI
bool has_callback);
// ExtensionFunctionDispatcher::Delegate
- virtual Browser* GetBrowser();
+ virtual Browser* GetBrowser() const;
virtual ExtensionDOMUI* GetExtensionDOMUI() { return this; }
+ virtual gfx::NativeWindow GetFrameNativeWindow();
// ExtensionPopupHost::Delegate
virtual RenderViewHost* GetRenderViewHost();
+ virtual Profile* GetProfile();
// BrowserURLHandler
static bool HandleChromeURLOverride(GURL* url, Profile* profile);
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 071c6f1..c1cb333 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -7,6 +7,8 @@
#include "base/process_util.h"
#include "base/singleton.h"
#include "base/values.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/execute_code_in_tab_function.h"
#include "chrome/browser/extensions/extension_bookmarks_module.h"
#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
@@ -181,6 +183,20 @@ ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
}; // namespace
+// ExtensionFunctionDispatcher::Delegate ---------------------------------------
+
+gfx::NativeWindow ExtensionFunctionDispatcher::Delegate::
+ GetFrameNativeWindow() {
+ Browser* browser = GetBrowser();
+ // If a browser is bound to this dispatcher, then return the widget hosting
+ // the window. Extensions hosted in ExternalTabContainer objects may not
+ // have a running browser instance.
+ if (browser)
+ return browser->window()->GetNativeHandle();
+
+ return NULL;
+}
+
// ExtensionFunctionDispatcher -------------------------------------------------
void ExtensionFunctionDispatcher::GetAllFunctionNames(
@@ -318,3 +334,7 @@ void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
Profile* ExtensionFunctionDispatcher::profile() {
return render_view_host_->process()->profile();
}
+
+gfx::NativeWindow ExtensionFunctionDispatcher::GetFrameNativeWindow() {
+ return delegate_ ? delegate_->GetFrameNativeWindow() : NULL;
+}
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index df50ceb..b35c069 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -9,6 +9,7 @@
#include <set>
#include <vector>
+#include "app/gfx/native_widget_types.h"
#include "base/ref_counted.h"
#include "googleurl/src/gurl.h"
@@ -33,7 +34,12 @@ class ExtensionFunctionDispatcher {
public:
class Delegate {
public:
- virtual Browser* GetBrowser() = 0;
+ virtual Browser* GetBrowser() const = 0;
+
+ // Returns the gfx::NativeWindow that contains the view hosting the
+ // environment in which the function dispatcher resides.
+ virtual gfx::NativeWindow GetFrameNativeWindow();
+
virtual ExtensionHost* GetExtensionHost() { return NULL; }
virtual ExtensionDOMUI* GetExtensionDOMUI() { return NULL; }
};
@@ -94,6 +100,12 @@ class ExtensionFunctionDispatcher {
// non-tab-hosted extension pages, this will return NULL.
ExtensionDOMUI* GetExtensionDOMUI();
+ // Returns the gfx::NativeWindow that frames the view of the extension
+ // containing the function dispatcher. This may return NULL. Refer to the
+ // ExtensionFunctionDispatcher::Delegate::GetFrameNativeWindow()
+ // implementation for an explanation.
+ gfx::NativeWindow GetFrameNativeWindow();
+
// Gets the extension the function is being invoked by. This should not ever
// return NULL.
Extension* GetExtension();
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 0ad3a9e..77bee6c 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -549,7 +549,7 @@ void ExtensionHost::HandleMouseLeave() {
#endif
}
-Browser* ExtensionHost::GetBrowser() {
+Browser* ExtensionHost::GetBrowser() const {
if (view_.get())
return view_->browser();
@@ -604,16 +604,19 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
}
int ExtensionHost::GetBrowserWindowID() const {
+ // Hosts not attached to any browser window have an id of -1. This includes
+ // those mentioned below, and background pages.
int window_id = -1;
if (extension_host_type_ == ViewType::EXTENSION_TOOLSTRIP ||
extension_host_type_ == ViewType::EXTENSION_MOLE ||
extension_host_type_ == ViewType::EXTENSION_POPUP) {
- window_id = ExtensionTabUtil::GetWindowId(
- const_cast<ExtensionHost* >(this)->GetBrowser());
- } else if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) {
- // Background page is not attached to any browser window, so pass -1.
- window_id = -1;
- } else {
+ // If the host is bound to a browser, then extract its window id.
+ // Extensions hosted in ExternalTabContainer objects may not have
+ // an associated browser.
+ Browser* browser = GetBrowser();
+ if (browser)
+ window_id = ExtensionTabUtil::GetWindowId(browser);
+ } else if (extension_host_type_ != ViewType::EXTENSION_BACKGROUND_PAGE) {
NOTREACHED();
}
return window_id;
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 76f20d2..5a27030 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -65,7 +65,10 @@ class ExtensionHost : public ExtensionPopupHost::PopupDelegate,
void* view() const { return NULL; }
#endif
- // Create an ExtensionView and tie it to this host and |browser|.
+ // Create an ExtensionView and tie it to this host and |browser|. Note NULL
+ // is a valid argument for |browser|. Extension views may be bound to
+ // tab-contents hosted in ExternalTabContainer objects, which do not
+ // instantiate Browser objects.
void CreateView(Browser* browser);
Extension* extension() { return extension_; }
@@ -187,7 +190,7 @@ class ExtensionHost : public ExtensionPopupHost::PopupDelegate,
// If this ExtensionHost has a view, this returns the Browser that view is a
// part of. If this is a global background page, we use the active Browser
// instead.
- virtual Browser* GetBrowser();
+ virtual Browser* GetBrowser() const;
virtual ExtensionHost* GetExtensionHost() { return this; }
// ExtensionPopupHost::Delegate
diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc
index 091fa71..f68553c 100644
--- a/chrome/browser/extensions/extension_popup_api.cc
+++ b/chrome/browser/extensions/extension_popup_api.cc
@@ -139,8 +139,12 @@ bool PopupShowFunction::RunImpl() {
BubbleBorder::ArrowLocation arrow_location =
(NULL != dispatcher()->GetExtensionHost()) ? BubbleBorder::BOTTOM_LEFT :
BubbleBorder::TOP_LEFT;
- popup_ = ExtensionPopup::Show(url, dispatcher()->GetBrowser(), rect,
- arrow_location, give_focus);
+ popup_ = ExtensionPopup::Show(url, dispatcher()->GetBrowser(),
+ dispatcher()->profile(),
+ dispatcher()->GetFrameNativeWindow(),
+ rect,
+ arrow_location,
+ give_focus);
ExtensionPopupHost* popup_host = dispatcher()->GetPopupHost();
DCHECK(popup_host);
diff --git a/chrome/browser/extensions/extension_popup_apitest.cc b/chrome/browser/extensions/extension_popup_apitest.cc
index 16c5374..6095d5d 100644
--- a/chrome/browser/extensions/extension_popup_apitest.cc
+++ b/chrome/browser/extensions/extension_popup_apitest.cc
@@ -12,5 +12,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_Popup) {
switches::kEnableExperimentalExtensionApis);
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExtensionToolstrips);
+
ASSERT_TRUE(RunExtensionTest("popup_api")) << message_;
}
diff --git a/chrome/browser/extensions/extension_popup_host.cc b/chrome/browser/extensions/extension_popup_host.cc
index f263494..1a964da 100644
--- a/chrome/browser/extensions/extension_popup_host.cc
+++ b/chrome/browser/extensions/extension_popup_host.cc
@@ -18,6 +18,13 @@
#include "chrome/common/notification_type.h"
+ExtensionPopupHost::PopupDelegate::~PopupDelegate() {
+ // If the PopupDelegate is being torn down, then make sure to reset the
+ // cached pointer in the host to prevent access to a stale pointer.
+ if (popup_host_.get())
+ popup_host_->RevokeDelegate();
+}
+
ExtensionPopupHost* ExtensionPopupHost::PopupDelegate::popup_host() {
if (!popup_host_.get())
popup_host_.reset(new ExtensionPopupHost(this));
@@ -25,6 +32,18 @@ ExtensionPopupHost* ExtensionPopupHost::PopupDelegate::popup_host() {
return popup_host_.get();
}
+Profile* ExtensionPopupHost::PopupDelegate::GetProfile() {
+ // If there is a browser present, return the profile associated with it.
+ // When hosting a view in an ExternalTabContainer, it is possible to have
+ // no Browser instance.
+ Browser* browser = GetBrowser();
+ if (browser) {
+ return browser->profile();
+ }
+
+ return NULL;
+}
+
ExtensionPopupHost::ExtensionPopupHost(PopupDelegate* delegate)
: // NO LINT
#if defined(TOOLKIT_VIEWS)
@@ -35,8 +54,10 @@ ExtensionPopupHost::ExtensionPopupHost(PopupDelegate* delegate)
// Listen for view close requests, so that we can dismiss a hosted pop-up
// view, if necessary.
+ Profile* profile = delegate_->GetProfile();
+ DCHECK(profile);
registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
- Source<Profile>(delegate_->GetBrowser()->profile()));
+ Source<Profile>(profile));
}
ExtensionPopupHost::~ExtensionPopupHost() {
@@ -88,9 +109,11 @@ void ExtensionPopupHost::DismissPopup() {
delete child_popup_;
child_popup_ = NULL;
- PopupEventRouter::OnPopupClosed(
- delegate_->GetBrowser()->profile(),
- delegate_->GetRenderViewHost()->routing_id());
+ if (delegate_) {
+ PopupEventRouter::OnPopupClosed(
+ delegate_->GetProfile(),
+ delegate_->GetRenderViewHost()->routing_id());
+ }
}
#endif // defined(TOOLKIT_VIEWS)
}
diff --git a/chrome/browser/extensions/extension_popup_host.h b/chrome/browser/extensions/extension_popup_host.h
index f8e97a0..102c4ad 100644
--- a/chrome/browser/extensions/extension_popup_host.h
+++ b/chrome/browser/extensions/extension_popup_host.h
@@ -36,12 +36,14 @@ class ExtensionPopupHost : // NOLINT
class PopupDelegate {
public:
PopupDelegate() {}
- virtual ~PopupDelegate() {}
- virtual Browser* GetBrowser() = 0;
+ virtual ~PopupDelegate();
+ virtual Browser* GetBrowser() const = 0;
virtual RenderViewHost* GetRenderViewHost() = 0;
+ virtual Profile* GetProfile();
// Constructs, or returns the existing ExtensionPopupHost instance.
ExtensionPopupHost* popup_host();
+
private:
scoped_ptr<ExtensionPopupHost> popup_host_;
@@ -51,6 +53,8 @@ class ExtensionPopupHost : // NOLINT
explicit ExtensionPopupHost(PopupDelegate* delegate);
virtual ~ExtensionPopupHost();
+ void RevokeDelegate() { delegate_ = NULL; }
+
// Dismiss the hosted pop-up, if one is present.
void DismissPopup();
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index 7d6ca0b..78cd214 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -52,6 +52,7 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile)
}
ExtensionProcessManager::~ExtensionProcessManager() {
+ CloseBackgroundHosts();
DCHECK(background_hosts_.empty());
}
@@ -60,7 +61,8 @@ ExtensionHost* ExtensionProcessManager::CreateView(Extension* extension,
Browser* browser,
ViewType::Type view_type) {
DCHECK(extension);
- DCHECK(browser);
+ // A NULL browser may only be given for pop-up views.
+ DCHECK(browser || (!browser && view_type == ViewType::EXTENSION_POPUP));
ExtensionHost* host =
#if defined(OS_MACOSX)
new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url,
@@ -76,7 +78,8 @@ ExtensionHost* ExtensionProcessManager::CreateView(Extension* extension,
ExtensionHost* ExtensionProcessManager::CreateView(const GURL& url,
Browser* browser,
ViewType::Type view_type) {
- DCHECK(browser);
+ // A NULL browser may only be given for pop-up views.
+ DCHECK(browser || (!browser && view_type == ViewType::EXTENSION_POPUP));
ExtensionsService* service =
browsing_instance_->profile()->GetExtensionsService();
if (service) {
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index 141a76b..d43df00 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -385,6 +385,10 @@ void ExternalTabContainer::ForwardMessageToExternalHost(
}
}
+gfx::NativeWindow ExternalTabContainer::GetFrameNativeWindow() {
+ return hwnd();
+}
+
bool ExternalTabContainer::TakeFocus(bool reverse) {
if (automation_) {
automation_->Send(new AutomationMsg_TabbedOut(0, tab_handle_,
@@ -677,6 +681,11 @@ void ExternalTabContainer::SetEnableExtensionAutomation(
}
}
+// ExternalTabContainer instances do not have a window.
+views::Window* ExternalTabContainer::GetWindow() {
+ return NULL;
+}
+
void ExternalTabContainer::Navigate(const GURL& url, const GURL& referrer) {
if (!tab_contents_) {
NOTREACHED();
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index 4461f7e..0d47d96 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -115,6 +115,7 @@ class ExternalTabContainer : public TabContentsDelegate,
virtual bool IsExternalTabContainer() const {
return true;
};
+ virtual gfx::NativeWindow GetFrameNativeWindow();
virtual bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
@@ -129,6 +130,8 @@ class ExternalTabContainer : public TabContentsDelegate,
const NavigationEntry::SSLStatus& ssl,
bool show_history);
+ virtual Browser* GetBrowser() { return browser_.get(); }
+
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,
const NotificationSource& source,
@@ -160,6 +163,9 @@ class ExternalTabContainer : public TabContentsDelegate,
void SetEnableExtensionAutomation(
const std::vector<std::string>& functions_enabled);
+ // Overridden from views::WidgetWin:
+ virtual views::Window* GetWindow();
+
protected:
// Overridden from views::WidgetWin:
virtual LRESULT OnCreate(LPCREATESTRUCT create_struct);
diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h
index 633910c..8e1379d 100644
--- a/chrome/browser/tab_contents/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents/tab_contents_delegate.h
@@ -16,6 +16,7 @@
#include "webkit/glue/context_menu.h"
#include "webkit/glue/window_open_disposition.h"
+class Browser;
class DownloadItem;
class ExtensionFunctionDispatcher;
class GURL;
@@ -251,6 +252,12 @@ class TabContentsDelegate {
int32 page_id) {
}
+ // Returns the browser in which the tab contents is being displayed.
+ virtual Browser* GetBrowser() { return NULL; }
+
+ // Returns the widget framing the view containing the tab contents.
+ virtual gfx::NativeWindow GetFrameNativeWindow() { return NULL; }
+
protected:
~TabContentsDelegate() {}
};
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index 999f3d3..6cc71e4 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -8,6 +8,8 @@
#include "app/resource_bundle.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
@@ -376,8 +378,13 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
gfx::Rect rect = button->bounds();
rect.set_x(origin.x());
rect.set_y(origin.y());
+
+ gfx::NativeWindow frame_window =
+ toolbar_->browser()->window()->GetNativeHandle();
popup_ = ExtensionPopup::Show(browser_action->popup_url(),
toolbar_->browser(),
+ toolbar_->browser()->profile(),
+ frame_window,
rect,
BubbleBorder::TOP_RIGHT,
true); // Activate the popup window.
diff --git a/chrome/browser/views/browser_bubble.cc b/chrome/browser/views/browser_bubble.cc
index 087b3b5..6712082 100644
--- a/chrome/browser/views/browser_bubble.cc
+++ b/chrome/browser/views/browser_bubble.cc
@@ -9,6 +9,21 @@
#include "views/widget/root_view.h"
#include "views/window/window.h"
+namespace {
+
+BrowserView* GetBrowserViewFromFrame(views::Widget* frame) {
+ BrowserView* browser_view = NULL;
+ views::Window* window = frame->GetWindow();
+ if (window) {
+ browser_view = BrowserView::GetBrowserViewForNativeWindow(
+ window->GetNativeWindow());
+ DCHECK(browser_view);
+ }
+ return browser_view;
+}
+
+} // namespace
+
BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame,
const gfx::Point& origin)
: frame_(frame),
@@ -39,8 +54,8 @@ void BrowserBubble::DetachFromBrowser() {
if (!attached_)
return;
attached_ = false;
- BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(
- frame_->GetWindow()->GetNativeWindow());
+
+ BrowserView* browser_view = GetBrowserViewFromFrame(frame_);
if (browser_view)
browser_view->DetachBrowserBubble(this);
}
@@ -49,13 +64,12 @@ void BrowserBubble::AttachToBrowser() {
DCHECK(!attached_);
if (attached_)
return;
- BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(
- frame_->GetWindow()->GetNativeWindow());
- DCHECK(browser_view);
- if (browser_view) {
+
+ BrowserView* browser_view = GetBrowserViewFromFrame(frame_);
+ if (browser_view)
browser_view->AttachBrowserBubble(this);
- attached_ = true;
- }
+
+ attached_ = true;
}
void BrowserBubble::BrowserWindowMoved() {
diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc
index c9c7ae6..6d8e4d6 100644
--- a/chrome/browser/views/extensions/extension_popup.cc
+++ b/chrome/browser/views/extensions/extension_popup.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/views/extensions/extension_popup.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/extensions/extension_process_manager.h"
@@ -27,7 +28,7 @@ const int ExtensionPopup::kMaxWidth = 800;
const int ExtensionPopup::kMaxHeight = 600;
ExtensionPopup::ExtensionPopup(ExtensionHost* host,
- Widget* frame,
+ views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show)
@@ -79,7 +80,8 @@ void ExtensionPopup::Show(bool activate) {
return;
#if defined(OS_WIN)
- frame_->GetWindow()->DisableInactiveRendering();
+ if (frame_->GetWindow())
+ frame_->GetWindow()->DisableInactiveRendering();
#endif
ResizeToView();
@@ -142,20 +144,32 @@ void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
// static
ExtensionPopup* ExtensionPopup::Show(
- const GURL& url, Browser* browser,
+ const GURL& url,
+ Browser* browser,
+ Profile* profile,
+ gfx::NativeWindow frame_window,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show) {
- ExtensionProcessManager* manager =
- browser->profile()->GetExtensionProcessManager();
+ DCHECK(profile);
+ DCHECK(frame_window);
+ ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
DCHECK(manager);
if (!manager)
return NULL;
+ // If no Browser instance was given, attempt to look up one matching the given
+ // profile.
+ if (!browser)
+ browser = BrowserList::FindBrowserWithProfile(profile);
+
+ Widget* frame_widget = Widget::GetWidgetFromNativeWindow(frame_window);
+ DCHECK(frame_widget);
+ if (!frame_widget)
+ return NULL;
+
ExtensionHost* host = manager->CreatePopup(url, browser);
- views::Widget* frame = BrowserView::GetBrowserViewForNativeWindow(
- browser->window()->GetNativeHandle())->GetWidget();
- ExtensionPopup* popup = new ExtensionPopup(host, frame, relative_to,
+ ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
arrow_location, activate_on_show);
// If the host had somehow finished loading, then we'd miss the notification
diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h
index 4c3ca11..92eab93 100644
--- a/chrome/browser/views/extensions/extension_popup.h
+++ b/chrome/browser/views/extensions/extension_popup.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
#define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
+#include "app/gfx/native_widget_types.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/views/browser_bubble.h"
#include "chrome/browser/views/extensions/extension_view.h"
@@ -15,6 +16,11 @@
class Browser;
class ExtensionHost;
+class Profile;
+
+namespace views {
+class Widget;
+}
class ExtensionPopup : public BrowserBubble,
public NotificationObserver,
@@ -24,6 +30,12 @@ class ExtensionPopup : public BrowserBubble,
// Create and show a popup with |url| positioned adjacent to |relative_to| in
// screen coordinates.
+ // |browser| is the browser to which the pop-up will be attached. NULL is a
+ // valid parameter for pop-ups not associated with a browser.
+ // |profile| is the user profile instance associated with the popup. A
+ // non NULL value must be given.
+ // |frame_window| is the native window that hosts the view inside which the
+ // popup will be anchored.
// The positioning of the pop-up is determined by |arrow_location| according
// to the following logic: The popup is anchored so that the corner indicated
// by value of |arrow_location| remains fixed during popup resizes.
@@ -34,6 +46,8 @@ class ExtensionPopup : public BrowserBubble,
// The actual display of the popup is delayed until the page contents
// finish loading in order to minimize UI flashing and resizing.
static ExtensionPopup* Show(const GURL& url, Browser* browser,
+ Profile* profile,
+ gfx::NativeWindow frame_window,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show);
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index 03f8437..d8c41e0 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -17,6 +17,7 @@
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/alternate_nav_url_fetcher.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_window.h"
#include "chrome/browser/bubble_positioner.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
@@ -1335,6 +1336,7 @@ void LocationBarView::PageActionImageView::ExecuteAction(int button) {
Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
if (!browser)
browser = BrowserList::FindBrowserWithProfile(profile_);
+ DCHECK(browser);
bool popup_showing = popup_ != NULL;
@@ -1351,8 +1353,11 @@ void LocationBarView::PageActionImageView::ExecuteAction(int button) {
gfx::Rect rect = parent->bounds();
rect.set_x(origin.x());
rect.set_y(origin.y());
+
popup_ = ExtensionPopup::Show(page_action_->popup_url(),
browser,
+ browser->profile(),
+ browser->window()->GetNativeHandle(),
rect,
BubbleBorder::TOP_RIGHT,
true); // Activate the popup window.