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

Unified Diff: chrome/browser/views/extensions/extension_popup.cc

Issue 1001002: Initial support for inspecting extension popups. (Closed)
Patch Set: pre submit Created 10 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/views/extensions/extension_popup.cc
diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc
index c417e8e2c78cd0181ee16ee73f2ff05c51fd95e0..6755c0de8b8518cc8e17357a0889f9e50c1d0d94 100644
--- a/chrome/browser/views/extensions/extension_popup.cc
+++ b/chrome/browser/views/extensions/extension_popup.cc
@@ -7,8 +7,12 @@
#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/debugger/devtools_manager.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
@@ -46,7 +50,9 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show,
- PopupChrome chrome)
+ bool inspect_with_devtools,
+ PopupChrome chrome,
+ Observer* observer)
: BrowserBubble(host->view(),
frame,
gfx::Point(),
@@ -57,16 +63,28 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
relative_to_(relative_to),
extension_host_(host),
activate_on_show_(activate_on_show),
+ inspect_with_devtools_(inspect_with_devtools),
+ close_on_lost_focus_(true),
+ closing_(false),
border_widget_(NULL),
border_(NULL),
border_view_(NULL),
popup_chrome_(chrome),
+ observer_(observer),
anchor_position_(arrow_location) {
+ AddRef(); // Balanced in Close();
+ set_delegate(this);
host->view()->SetContainer(this);
+
+ // We wait to show the popup until the contained host finishes loading.
registrar_.Add(this,
NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
Source<Profile>(host->profile()));
+ // Listen for the containing view calling window.close();
+ registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
+ Source<Profile>(host->profile()));
+
// TODO(erikkay) Some of this border code is derived from InfoBubble.
// We should see if we can unify these classes.
@@ -167,16 +185,81 @@ void ExtensionPopup::ResizeToView() {
}
}
+void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) {
+ if (!closing_)
+ Close();
+ // TODO(rafaelw) -- the border must move as well.
+}
+
+void ExtensionPopup::BubbleBrowserWindowClosing(BrowserBubble* bubble) {
+ if (!closing_)
+ Close();
+}
+
+void ExtensionPopup::BubbleGotFocus(BrowserBubble* bubble) {
+ // Forward the focus to the renderer.
+ host()->render_view_host()->view()->Focus();
+}
+
+void ExtensionPopup::BubbleLostFocus(BrowserBubble* bubble,
+ bool lost_focus_to_child) {
+ if (closing_ || // We are already closing.
+ inspect_with_devtools_ || // The popup is being inspected.
+ !close_on_lost_focus_ || // Our client is handling focus listening.
+ lost_focus_to_child) // A child of this view got focus.
+ return;
+
+ // When we do close on BubbleLostFocus, we do it in the next event loop
+ // because a subsequent event in this loop may also want to close this popup
+ // and if so, we want to allow that. Example: Clicking the same browser
+ // action button that opened the popup. If we closed immediately, the
+ // browser action container would fail to discover that the same button
+ // was pressed.
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &ExtensionPopup::Close));
+}
+
+
void ExtensionPopup::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- if (type == NotificationType::EXTENSION_HOST_DID_STOP_LOADING) {
- // Once we receive did stop loading, the content will be complete and
- // the width will have been computed. Now it's safe to show.
- if (extension_host_.get() == Details<ExtensionHost>(details).ptr())
- Show(activate_on_show_);
- } else {
- NOTREACHED() << L"Received unexpected notification";
+ switch (type.value) {
+ case NotificationType::EXTENSION_HOST_DID_STOP_LOADING:
+ // Once we receive did stop loading, the content will be complete and
+ // the width will have been computed. Now it's safe to show.
+ if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) {
+ Show(activate_on_show_);
+
+ if (inspect_with_devtools_) {
+ // Listen for the the devtools window closing.
+ registrar_.Add(this, NotificationType::DEVTOOLS_WINDOW_CLOSING,
+ Source<Profile>(extension_host_->profile()));
+ DevToolsManager::GetInstance()->ToggleDevToolsWindow(
+ extension_host_->render_view_host(), true);
+ }
+ }
+ break;
+ case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
+ // If we aren't the host of the popup, then disregard the notification.
+ if (Details<ExtensionHost>(host()) != details)
+ return;
+ Close();
+
+ break;
+ case NotificationType::DEVTOOLS_WINDOW_CLOSING:
+ // Make sure its the devtools window that inspecting our popup.
+ if (Details<RenderViewHost>(extension_host_->render_view_host()) != details)
+ return;
+
+ // If the devtools window is closing, we post a task to ourselves to
+ // close the popup. This gives the devtools window a chance to finish
+ // detaching from the inspected RenderViewHost.
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &ExtensionPopup::Close));
+
+ break;
+ default:
+ NOTREACHED() << L"Received unexpected notification";
}
}
@@ -232,7 +315,9 @@ ExtensionPopup* ExtensionPopup::Show(
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show,
- PopupChrome chrome) {
+ bool inspect_with_devtools,
+ PopupChrome chrome,
+ Observer* observer) {
DCHECK(profile);
DCHECK(frame_window);
ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
@@ -253,7 +338,8 @@ ExtensionPopup* ExtensionPopup::Show(
ExtensionHost* host = manager->CreatePopup(url, browser);
ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
arrow_location, activate_on_show,
- chrome);
+ inspect_with_devtools, chrome,
+ observer);
// If the host had somehow finished loading, then we'd miss the notification
// and not show. This seems to happen in single-process mode.
@@ -262,3 +348,13 @@ ExtensionPopup* ExtensionPopup::Show(
return popup;
}
+
+void ExtensionPopup::Close() {
+ if (closing_)
+ return;
+ closing_ = true;
+ DetachFromBrowser();
+ if (observer_)
+ observer_->ExtensionPopupClosed(this);
+ Release(); // Balanced in ctor.
+}
« no previous file with comments | « chrome/browser/views/extensions/extension_popup.h ('k') | chrome/browser/views/infobars/extension_infobar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698