summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/main_menu.h5
-rw-r--r--chrome/browser/cocoa/extension_view_mac.h5
-rw-r--r--chrome/browser/cocoa/extension_view_mac.mm4
-rw-r--r--chrome/browser/extensions/browser_action_apitest.cc33
-rw-r--r--chrome/browser/extensions/extension_host.cc6
-rw-r--r--chrome/browser/extensions/extension_host.h2
-rw-r--r--chrome/browser/gtk/extension_view_gtk.cc4
-rw-r--r--chrome/browser/gtk/extension_view_gtk.h5
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc9
-rw-r--r--chrome/browser/renderer_host/render_view_host.h2
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h5
-rw-r--r--chrome/browser/tab_contents/interstitial_page.cc6
-rw-r--r--chrome/browser/tab_contents/tab_contents_view.cc4
-rw-r--r--chrome/browser/tab_contents/tab_contents_view.h2
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.mm2
-rw-r--r--chrome/browser/views/browser_actions_container.cc29
-rw-r--r--chrome/browser/views/browser_actions_container.h10
-rw-r--r--chrome/browser/views/extensions/extension_popup.cc27
-rw-r--r--chrome/browser/views/extensions/extension_popup.h14
-rw-r--r--chrome/browser/views/extensions/extension_shelf.h2
-rw-r--r--chrome/browser/views/extensions/extension_view.cc29
-rw-r--r--chrome/browser/views/extensions/extension_view.h28
-rw-r--r--chrome/common/extensions/extension.cc11
-rw-r--r--chrome/common/extensions/extension_action.h4
-rw-r--r--chrome/common/render_messages_internal.h10
-rw-r--r--chrome/renderer/render_view.cc32
-rw-r--r--chrome/renderer/render_view.h12
-rwxr-xr-xchrome/test/data/extensions/api_test/popup/chromium.pngbin0 -> 1736 bytes
-rwxr-xr-xchrome/test/data/extensions/api_test/popup/manifest.json10
-rwxr-xr-xchrome/test/data/extensions/api_test/popup/popup.html44
-rw-r--r--chrome/test/data/extensions/samples/buildbot/manifest.json2
-rwxr-xr-xchrome/test/data/extensions/samples/buildbot/popup.html32
32 files changed, 273 insertions, 117 deletions
diff --git a/chrome/browser/chromeos/main_menu.h b/chrome/browser/chromeos/main_menu.h
index 2d896fc..11e9942 100644
--- a/chrome/browser/chromeos/main_menu.h
+++ b/chrome/browser/chromeos/main_menu.h
@@ -18,6 +18,9 @@ class Browser;
class RenderWidgetHostViewGtk;
class SiteInstance;
+namespace gfx {
+class Size;
+}
namespace views {
class WidgetGtk;
}
@@ -162,7 +165,7 @@ class MainMenu : public RenderViewHostDelegate,
virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {}
virtual void HandleMouseEvent() {}
virtual void HandleMouseLeave() {}
- virtual void UpdatePreferredWidth(int pref_width) {}
+ virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
// The currently active browser. We use this to open urls.
Browser* browser_;
diff --git a/chrome/browser/cocoa/extension_view_mac.h b/chrome/browser/cocoa/extension_view_mac.h
index 8abb481..4ce4c13 100644
--- a/chrome/browser/cocoa/extension_view_mac.h
+++ b/chrome/browser/cocoa/extension_view_mac.h
@@ -7,6 +7,7 @@
#include "app/gfx/native_widget_types.h"
#include "base/basictypes.h"
+#include "base/gfx/size.h"
#include "third_party/skia/include/core/SkBitmap.h"
class Browser;
@@ -40,9 +41,9 @@ class ExtensionViewMac {
// Sets the extensions's background image.
void SetBackground(const SkBitmap& background);
- // Method for the ExtensionHost to notify us about the correct width for
+ // Method for the ExtensionHost to notify us about the correct size for
// extension contents.
- void UpdatePreferredWidth(int pref_width);
+ void UpdatePreferredSize(const gfx::Size& new_size);
// Method for the ExtensionHost to notify us when the RenderViewHost has a
// connection.
diff --git a/chrome/browser/cocoa/extension_view_mac.mm b/chrome/browser/cocoa/extension_view_mac.mm
index c9844b3..171cc30 100644
--- a/chrome/browser/cocoa/extension_view_mac.mm
+++ b/chrome/browser/cocoa/extension_view_mac.mm
@@ -44,7 +44,7 @@ void ExtensionViewMac::SetBackground(const SkBitmap& background) {
}
}
-void ExtensionViewMac::UpdatePreferredWidth(int pref_width) {
+void ExtensionViewMac::UpdatePreferredSize(const gfx::Size& new_size) {
// TODO(thakis, erikkay): Windows does some tricks to resize the extension
// view not before it's visible. Do something similar here.
@@ -52,7 +52,7 @@ void ExtensionViewMac::UpdatePreferredWidth(int pref_width) {
// resizing.
NSView* view = native_view();
NSRect frame = [view frame];
- frame.size.width = pref_width;
+ frame.size.width = new_size.width();
// RenderWidgetHostViewCocoa overrides setFrame but not setFrameSize.
[view setFrame:frame];
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc
index 692e74e..5a7c086 100644
--- a/chrome/browser/extensions/browser_action_apitest.cc
+++ b/chrome/browser/extensions/browser_action_apitest.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/browser_actions_container.h"
+#include "chrome/browser/views/extensions/extension_popup.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/test/ui_test_utils.h"
@@ -62,7 +63,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, BrowserAction) {
ASSERT_TRUE(result);
}
-
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DynamicBrowserAction) {
ASSERT_TRUE(RunExtensionTest("browser_action_no_icon")) << message_;
@@ -84,3 +84,34 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DynamicBrowserAction) {
ExtensionActionState* action_state = extension->browser_action_state();
ASSERT_TRUE(action_state->icon());
}
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, BrowserActionPopup) {
+ ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("popup")));
+
+ ResultCatcher catcher;
+ BrowserActionsContainer* browser_actions =
+ browser()->window()->GetBrowserWindowTesting()->GetToolbarView()->
+ browser_actions();
+
+ // Simulate a click on the browser action and verify the size of the resulting
+ // popup.
+ browser_actions->TestExecuteBrowserAction(0);
+ EXPECT_TRUE(browser_actions->TestGetPopup() != NULL);
+ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
+ gfx::Rect bounds = browser_actions->TestGetPopup()->view()->bounds();
+ EXPECT_EQ(100, bounds.width());
+ EXPECT_EQ(100, bounds.height());
+ browser_actions->HidePopup();
+ EXPECT_TRUE(browser_actions->TestGetPopup() == NULL);
+
+ // Do it again, and verify the new bigger size (the popup grows each time it's
+ // opened).
+ browser_actions->TestExecuteBrowserAction(0);
+ EXPECT_TRUE(browser_actions->TestGetPopup() != NULL);
+ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
+ bounds = browser_actions->TestGetPopup()->view()->bounds();
+ EXPECT_EQ(200, bounds.width());
+ EXPECT_EQ(200, bounds.height());
+ browser_actions->HidePopup();
+ EXPECT_TRUE(browser_actions->TestGetPopup() == NULL);
+}
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 8b45d4c..5413cd7 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -213,9 +213,9 @@ void ExtensionHost::Observe(NotificationType type,
}
}
-void ExtensionHost::UpdatePreferredWidth(int pref_width) {
+void ExtensionHost::UpdatePreferredSize(const gfx::Size& new_size) {
if (view_.get())
- view_->UpdatePreferredWidth(pref_width);
+ view_->UpdatePreferredSize(new_size);
}
void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host) {
@@ -503,7 +503,7 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
extension_function_dispatcher_.reset(
new ExtensionFunctionDispatcher(render_view_host, this, url_));
- render_view_host->Send(new ViewMsg_EnableIntrinsicWidthChangedMode(
+ render_view_host->Send(new ViewMsg_EnablePreferredSizeChangedMode(
render_view_host->routing_id()));
}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index ba145b4..0c43067 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -134,7 +134,7 @@ class ExtensionHost : public RenderViewHostDelegate,
virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
virtual void HandleMouseEvent();
virtual void HandleMouseLeave();
- virtual void UpdatePreferredWidth(int pref_width);
+ virtual void UpdatePreferredSize(const gfx::Size& new_size);
// NotificationObserver
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/gtk/extension_view_gtk.cc b/chrome/browser/gtk/extension_view_gtk.cc
index 55f7883..d7a4fca 100644
--- a/chrome/browser/gtk/extension_view_gtk.cc
+++ b/chrome/browser/gtk/extension_view_gtk.cc
@@ -36,8 +36,8 @@ void ExtensionViewGtk::SetBackground(const SkBitmap& background) {
}
}
-void ExtensionViewGtk::UpdatePreferredWidth(int pref_width) {
- gtk_widget_set_size_request(native_view(), pref_width, -1);
+void ExtensionViewGtk::UpdatePreferredSize(const gfx::Size& new_size) {
+ gtk_widget_set_size_request(native_view(), new_size.width(), -1);
}
void ExtensionViewGtk::CreateWidgetHostView() {
diff --git a/chrome/browser/gtk/extension_view_gtk.h b/chrome/browser/gtk/extension_view_gtk.h
index 6f67f53..16b7892 100644
--- a/chrome/browser/gtk/extension_view_gtk.h
+++ b/chrome/browser/gtk/extension_view_gtk.h
@@ -7,6 +7,7 @@
#include "app/gfx/native_widget_types.h"
#include "base/basictypes.h"
+#include "base/gfx/size.h"
#include "third_party/skia/include/core/SkBitmap.h"
class Browser;
@@ -29,9 +30,9 @@ class ExtensionViewGtk {
void SetBackground(const SkBitmap& background);
- // Method for the ExtensionHost to notify us about the correct width for
+ // Method for the ExtensionHost to notify us about the correct size for
// extension contents.
- void UpdatePreferredWidth(int pref_width);
+ void UpdatePreferredSize(const gfx::Size& new_size);
// Method for the ExtensionHost to notify us when the RenderViewHost has a
// connection.
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 5ebe328..d8b86a7 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -764,8 +764,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDownloadFavIcon, OnMsgDidDownloadFavIcon)
IPC_MESSAGE_HANDLER(ViewHostMsg_ContextMenu, OnMsgContextMenu)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenURL, OnMsgOpenURL)
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredWidthChange,
- OnMsgDidContentsPreferredWidthChange)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
+ OnMsgDidContentsPreferredSizeChange)
IPC_MESSAGE_HANDLER(ViewHostMsg_DomOperationResponse,
OnMsgDomOperationResponse)
IPC_MESSAGE_HANDLER(ViewHostMsg_DOMUISend,
@@ -1189,11 +1189,12 @@ void RenderViewHost::OnMsgOpenURL(const GURL& url,
delegate_->RequestOpenURL(validated_url, referrer, disposition);
}
-void RenderViewHost::OnMsgDidContentsPreferredWidthChange(int pref_width) {
+void RenderViewHost::OnMsgDidContentsPreferredSizeChange(
+ const gfx::Size& new_size) {
RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
if (!view)
return;
- view->UpdatePreferredWidth(pref_width);
+ view->UpdatePreferredSize(new_size);
}
void RenderViewHost::OnMsgDomOperationResponse(
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index acb1833..f6c1733 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -503,7 +503,7 @@ class RenderViewHost : public RenderWidgetHost,
void OnMsgContextMenu(const ContextMenuParams& params);
void OnMsgOpenURL(const GURL& url, const GURL& referrer,
WindowOpenDisposition disposition);
- void OnMsgDidContentsPreferredWidthChange(int pref_width);
+ void OnMsgDidContentsPreferredSizeChange(const gfx::Size& new_size);
void OnMsgDomOperationResponse(const std::string& json_string,
int automation_id);
void OnMsgDOMUISend(const std::string& message,
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index cb1d008..0e054d4 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -42,6 +42,7 @@ class WaitableEvent;
namespace gfx {
class Rect;
+class Size;
}
namespace IPC {
@@ -140,8 +141,8 @@ class RenderViewHostDelegate {
virtual void HandleMouseEvent() = 0;
virtual void HandleMouseLeave() = 0;
- // The content's intrinsic width (prefWidth) changed.
- virtual void UpdatePreferredWidth(int pref_width) = 0;
+ // The contents' preferred size changed.
+ virtual void UpdatePreferredSize(const gfx::Size& pref_size) = 0;
};
// RendererManagerment -------------------------------------------------------
diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc
index 042801a..cb6648a 100644
--- a/chrome/browser/tab_contents/interstitial_page.cc
+++ b/chrome/browser/tab_contents/interstitial_page.cc
@@ -105,7 +105,7 @@ class InterstitialPage::InterstitialPageRVHViewDelegate
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update);
- virtual void UpdatePreferredWidth(int pref_width);
+ virtual void UpdatePreferredSize(const gfx::Size& pref_size);
private:
InterstitialPage* interstitial_page_;
@@ -569,8 +569,8 @@ void InterstitialPage::InterstitialPageRVHViewDelegate::UpdateDragCursor(
void InterstitialPage::InterstitialPageRVHViewDelegate::GotFocus() {
}
-void InterstitialPage::InterstitialPageRVHViewDelegate::UpdatePreferredWidth(
- int pref_width) {
+void InterstitialPage::InterstitialPageRVHViewDelegate::UpdatePreferredSize(
+ const gfx::Size& pref_size) {
}
void InterstitialPage::InterstitialPageRVHViewDelegate::TakeFocus(
diff --git a/chrome/browser/tab_contents/tab_contents_view.cc b/chrome/browser/tab_contents/tab_contents_view.cc
index 99a052a..2b8ae76 100644
--- a/chrome/browser/tab_contents/tab_contents_view.cc
+++ b/chrome/browser/tab_contents/tab_contents_view.cc
@@ -23,8 +23,8 @@ void TabContentsView::RenderViewCreated(RenderViewHost* host) {
// Default implementation does nothing. Platforms may override.
}
-void TabContentsView::UpdatePreferredWidth(int pref_width) {
- preferred_width_ = pref_width;
+void TabContentsView::UpdatePreferredSize(const gfx::Size& pref_size) {
+ preferred_width_ = pref_size.width();
}
void TabContentsView::CreateNewWindow(int route_id) {
diff --git a/chrome/browser/tab_contents/tab_contents_view.h b/chrome/browser/tab_contents/tab_contents_view.h
index fcef017..db5fff8 100644
--- a/chrome/browser/tab_contents/tab_contents_view.h
+++ b/chrome/browser/tab_contents/tab_contents_view.h
@@ -123,7 +123,7 @@ class TabContentsView : public RenderViewHostDelegate::View {
virtual void HandleMouseLeave() {}
// Set and return the content's intrinsic width.
- virtual void UpdatePreferredWidth(int pref_width);
+ virtual void UpdatePreferredSize(const gfx::Size& pref_size);
int preferred_width() const {
return preferred_width_;
}
diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm
index c966ee8..3740a49 100644
--- a/chrome/browser/tab_contents/tab_contents_view_mac.mm
+++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm
@@ -131,7 +131,7 @@ void TabContentsViewMac::RenderViewCreated(RenderViewHost* host) {
// We want updates whenever the intrinsic width of the webpage
// changes. Put the RenderView into that mode.
int routing_id = host->routing_id();
- host->Send(new ViewMsg_EnableIntrinsicWidthChangedMode(routing_id));
+ host->Send(new ViewMsg_EnablePreferredSizeChangedMode(routing_id));
}
void TabContentsViewMac::SetPageTitle(const std::wstring& title) {
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index 4ce1197..aac8caf 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -271,6 +271,8 @@ class BrowserActionView : public views::View {
BrowserActionView(ExtensionAction* browser_action, Extension* extension,
BrowserActionsContainer* panel);
+ BrowserActionButton* button() { return button_; }
+
private:
virtual void Layout();
@@ -445,15 +447,30 @@ void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
void BrowserActionsContainer::HidePopup() {
if (popup_) {
- popup_->DetachFromBrowser();
- delete popup_;
+ // This sometimes gets called via a timer (See BubbleLostFocus), so clear
+ // the task factory. in case one is pending.
+ task_factory_.RevokeAll();
+
+ // Save these variables in local temporaries since destroying the popup
+ // calls BubbleLostFocus to be called, which will try to call HidePopup()
+ // again if popup_ is non-null.
+ ExtensionPopup* closing_popup = popup_;
+ BrowserActionButton* closing_button = popup_button_;
popup_ = NULL;
- popup_button_->PopupDidHide();
popup_button_ = NULL;
+
+ closing_popup->DetachFromBrowser();
+ delete closing_popup;
+ closing_button->PopupDidHide();
return;
}
}
+void BrowserActionsContainer::TestExecuteBrowserAction(int index) {
+ BrowserActionButton* button = browser_action_views_[index]->button();
+ OnBrowserActionExecuted(button);
+}
+
void BrowserActionsContainer::OnBrowserActionExecuted(
BrowserActionButton* button) {
const ExtensionAction& browser_action = button->browser_action();
@@ -478,8 +495,7 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
rect.set_y(origin.y());
popup_ = ExtensionPopup::Show(browser_action.popup_url(),
toolbar_->browser(),
- rect,
- browser_action.popup_height());
+ rect);
popup_->set_delegate(this);
popup_button_ = button;
popup_button_->PopupDidShow();
@@ -539,6 +555,9 @@ void BrowserActionsContainer::BubbleGotFocus(BrowserBubble* bubble) {
}
void BrowserActionsContainer::BubbleLostFocus(BrowserBubble* bubble) {
+ if (!popup_)
+ return;
+
// This is a bit annoying. If you click on the button that generated the
// current popup, then we first get this lost focus message, and then
// we get the click action. This results in the popup being immediately
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index f3b3863..c849d44 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -69,11 +69,17 @@ class BrowserActionsContainer : public views::View,
// by default irrespective of the available space to draw them.
int GetClippedPreferredWidth(int available_width);
- private:
-
// Hide the current popup.
void HidePopup();
+ // Simulate a click on a browser action button. This should only be
+ // used by unit tests.
+ void TestExecuteBrowserAction(int index);
+
+ // Retrieve the current popup. This should only be used by unit tests.
+ ExtensionPopup* TestGetPopup() { return popup_; }
+
+ private:
// The vector of browser actions (icons/image buttons for each action).
std::vector<BrowserActionView*> browser_action_views_;
diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc
index 0588664..53025e9 100644
--- a/chrome/browser/views/extensions/extension_popup.cc
+++ b/chrome/browser/views/extensions/extension_popup.cc
@@ -22,6 +22,7 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
: BrowserBubble(host->view(), frame, gfx::Point()),
relative_to_(relative_to),
extension_host_(host) {
+ host->view()->SetContainer(this);
registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
Source<Profile>(host->profile()));
@@ -51,8 +52,19 @@ void ExtensionPopup::Hide() {
}
void ExtensionPopup::Show() {
+ if (visible())
+ return;
+
ResizeToView();
+ // Show the border first, then the popup overlaid on top.
+ border_widget_->Show();
+ BrowserBubble::Show(true);
+}
+
+void ExtensionPopup::ResizeToView() {
+ BrowserBubble::ResizeToView();
+
// The rounded corners cut off more of the view than the border insets claim.
// Since we can't clip the ExtensionView's corners, we need to increase the
// inset by half the corner radius as well as lying about the size of the
@@ -73,10 +85,6 @@ void ExtensionPopup::Show() {
origin.set_x(origin.x() + border_insets.left() + corner_inset);
origin.set_y(origin.y() + border_insets.top() + corner_inset);
MoveTo(origin.x(), origin.y());
-
- // Show the border first, then the popup overlaid on top.
- border_widget_->Show();
- BrowserBubble::Show(true);
}
void ExtensionPopup::Observe(NotificationType type,
@@ -92,10 +100,14 @@ void ExtensionPopup::Observe(NotificationType type,
}
}
+void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
+ view->SizeToPreferredSize();
+ ResizeToView();
+}
+
// static
ExtensionPopup* ExtensionPopup::Show(const GURL& url, Browser* browser,
- const gfx::Rect& relative_to,
- int height) {
+ const gfx::Rect& relative_to) {
ExtensionProcessManager* manager =
browser->profile()->GetExtensionProcessManager();
DCHECK(manager);
@@ -106,9 +118,6 @@ ExtensionPopup* ExtensionPopup::Show(const GURL& url, Browser* browser,
views::Widget* frame = BrowserView::GetBrowserViewForNativeWindow(
browser->window()->GetNativeHandle())->GetWidget();
ExtensionPopup* popup = new ExtensionPopup(host, frame, relative_to);
- gfx::Size sz = host->view()->GetPreferredSize();
- sz.set_height(height);
- host->view()->SetPreferredSize(sz);
// If the host had somehow finished loading, then we'd miss the notification
// and not show. This seems to happen in single-process mode.
diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h
index 1e2ff73..5915f59 100644
--- a/chrome/browser/views/extensions/extension_popup.h
+++ b/chrome/browser/views/extensions/extension_popup.h
@@ -16,7 +16,8 @@ class Browser;
class ExtensionHost;
class ExtensionPopup : public BrowserBubble,
- public NotificationObserver {
+ public NotificationObserver,
+ public ExtensionView::Container {
public:
virtual ~ExtensionPopup();
@@ -27,20 +28,25 @@ 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,
- const gfx::Rect& relative_to,
- int height);
+ const gfx::Rect& relative_to);
ExtensionHost* host() const { return extension_host_.get(); }
// BrowserBubble overrides.
- virtual void Show();
virtual void Hide();
+ virtual void Show();
+ virtual void ResizeToView();
// NotificationObserver overrides.
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
+ // ExtensionView::Container overrides.
+ virtual void OnExtensionMouseEvent(ExtensionView* view) { };
+ virtual void OnExtensionMouseLeave(ExtensionView* view) { };
+ virtual void OnExtensionPreferredSizeChanged(ExtensionView* view);
+
private:
ExtensionPopup(ExtensionHost* host,
views::Widget* frame,
diff --git a/chrome/browser/views/extensions/extension_shelf.h b/chrome/browser/views/extensions/extension_shelf.h
index 08de605..3be5791 100644
--- a/chrome/browser/views/extensions/extension_shelf.h
+++ b/chrome/browser/views/extensions/extension_shelf.h
@@ -22,7 +22,7 @@ namespace views {
// A shelf that contains Extension toolstrips.
class ExtensionShelf : public DetachableToolbarView,
- public ExtensionContainer,
+ public ExtensionView::Container,
public ExtensionShelfModelObserver,
public AnimationDelegate,
public NotificationObserver {
diff --git a/chrome/browser/views/extensions/extension_view.cc b/chrome/browser/views/extensions/extension_view.cc
index f59d1a4..1d0cfc5 100644
--- a/chrome/browser/views/extensions/extension_view.cc
+++ b/chrome/browser/views/extensions/extension_view.cc
@@ -13,8 +13,10 @@
#include "views/widget/widget.h"
ExtensionView::ExtensionView(ExtensionHost* host, Browser* browser)
- : host_(host), browser_(browser),
- initialized_(false), pending_preferred_width_(0), container_(NULL),
+ : host_(host),
+ browser_(browser),
+ initialized_(false),
+ container_(NULL),
is_clipped_(false) {
host_->set_view(this);
}
@@ -110,7 +112,8 @@ void ExtensionView::ShowIfCompletelyLoaded() {
return;
}
SetVisible(true);
- UpdatePreferredWidth(pending_preferred_width_);
+
+ UpdatePreferredSize(pending_preferred_size_);
}
}
@@ -131,17 +134,17 @@ void ExtensionView::SetBackground(const SkBitmap& background) {
ShowIfCompletelyLoaded();
}
-void ExtensionView::UpdatePreferredWidth(int pref_width) {
+void ExtensionView::UpdatePreferredSize(const gfx::Size& new_size) {
// Don't actually do anything with this information until we have been shown.
// Size changes will not be honored by lower layers while we are hidden.
- gfx::Size preferred_size = GetPreferredSize();
if (!IsVisible()) {
- pending_preferred_width_ = pref_width;
- } else if (pref_width > 0 && pref_width != preferred_size.width()) {
- if (preferred_size.height() == 0)
- preferred_size.set_height(height());
- SetPreferredSize(gfx::Size(pref_width, preferred_size.height()));
+ pending_preferred_size_ = new_size;
+ return;
}
+
+ gfx::Size preferred_size = GetPreferredSize();
+ if (new_size != preferred_size)
+ SetPreferredSize(new_size);
}
void ExtensionView::ViewHierarchyChanged(bool is_add,
@@ -168,3 +171,9 @@ void ExtensionView::RenderViewCreated() {
pending_background_.reset();
}
}
+
+void ExtensionView::SetPreferredSize(const gfx::Size& size) {
+ views::NativeViewHost::SetPreferredSize(size);
+ if (container_)
+ container_->OnExtensionPreferredSizeChanged(this);
+}
diff --git a/chrome/browser/views/extensions/extension_view.h b/chrome/browser/views/extensions/extension_view.h
index 39b5851..8227771 100644
--- a/chrome/browser/views/extensions/extension_view.h
+++ b/chrome/browser/views/extensions/extension_view.h
@@ -17,21 +17,22 @@ class ExtensionHost;
class ExtensionView;
class RenderViewHost;
-// A class that represents the container that this view is in.
-// (bottom shelf, side bar, etc.)
-class ExtensionContainer {
- public:
- // Mouse event notifications from the view. (useful for hover UI).
- virtual void OnExtensionMouseEvent(ExtensionView* view) = 0;
- virtual void OnExtensionMouseLeave(ExtensionView* view) = 0;
-};
-
// This handles the display portion of an ExtensionHost.
class ExtensionView : public views::NativeViewHost {
public:
ExtensionView(ExtensionHost* host, Browser* browser);
~ExtensionView();
+ // A class that represents the container that this view is in.
+ // (bottom shelf, side bar, etc.)
+ class Container {
+ public:
+ // Mouse event notifications from the view. (useful for hover UI).
+ virtual void OnExtensionMouseEvent(ExtensionView* view) = 0;
+ virtual void OnExtensionMouseLeave(ExtensionView* view) = 0;
+ virtual void OnExtensionPreferredSizeChanged(ExtensionView* view) {}
+ };
+
ExtensionHost* host() const { return host_; }
Browser* browser() const { return browser_; }
Extension* extension() const;
@@ -40,7 +41,7 @@ class ExtensionView : public views::NativeViewHost {
void SetIsClipped(bool is_clipped);
// Notification from ExtensionHost.
- void UpdatePreferredWidth(int pref_width);
+ void UpdatePreferredSize(const gfx::Size& new_size);
void HandleMouseEvent();
void HandleMouseLeave();
@@ -52,7 +53,7 @@ class ExtensionView : public views::NativeViewHost {
void SetBackground(const SkBitmap& background);
// Sets the container for this view.
- void SetContainer(ExtensionContainer* container) { container_ = container; }
+ void SetContainer(Container* container) { container_ = container; }
// Overridden from views::NativeViewHost:
virtual void SetVisible(bool is_visible);
@@ -60,6 +61,7 @@ class ExtensionView : public views::NativeViewHost {
const gfx::Rect& current);
virtual void ViewHierarchyChanged(bool is_add,
views::View *parent, views::View *child);
+ virtual void SetPreferredSize(const gfx::Size& size);
private:
friend class ExtensionHost;
@@ -90,11 +92,11 @@ class ExtensionView : public views::NativeViewHost {
// What we should set the preferred width to once the ExtensionView has
// loaded.
- int pending_preferred_width_;
+ gfx::Size pending_preferred_size_;
// The container this view is in (not necessarily its direct superview).
// Note: the view does not own its container.
- ExtensionContainer* container_;
+ Container* container_;
// Whether this extension view is clipped.
bool is_clipped_;
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 1d34c97d..664b44a 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -367,14 +367,6 @@ ExtensionAction* Extension::LoadExtensionActionHelper(
return NULL;
}
result->set_popup_url(url);
-
- int height;
- if (!popup->GetInteger(keys::kPageActionPopupHeight, &height)) {
- *error = ExtensionErrorUtils::FormatErrorMessage(
- errors::kInvalidPageActionPopupHeight, "<missing>");
- return NULL;
- }
- result->set_popup_height(height);
} else if (!url_str.empty()) {
GURL url = GetResourceURL(url_str);
if (!url.is_valid()) {
@@ -383,9 +375,6 @@ ExtensionAction* Extension::LoadExtensionActionHelper(
return NULL;
}
result->set_popup_url(url);
- // TODO(erikkay): Need dynamic sizing of popups.
- // http://code.google.com/p/chromium/issues/detail?id=24471
- result->set_popup_height(100);
}
return result.release();
diff --git a/chrome/common/extensions/extension_action.h b/chrome/common/extensions/extension_action.h
index 2e34bbb..31fe0e7 100644
--- a/chrome/common/extensions/extension_action.h
+++ b/chrome/common/extensions/extension_action.h
@@ -52,9 +52,6 @@ class ExtensionAction {
const GURL& popup_url() const { return popup_url_; }
void set_popup_url(const GURL& url) { popup_url_ = url; }
- const int popup_height() const { return popup_height_; }
- void set_popup_height(int height) { popup_height_ = height; }
-
bool is_popup() const { return !popup_url_.is_empty(); }
private:
@@ -77,7 +74,6 @@ class ExtensionAction {
// If the action has a popup, it has a URL and a height.
GURL popup_url_;
- int popup_height_;
};
typedef std::map<std::string, ExtensionAction*> ExtensionActionMap;
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 7408ab8..ebff2dc 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -694,9 +694,8 @@ IPC_BEGIN_MESSAGES(View)
// the widget position while these asynchronous operations are in progress.
IPC_MESSAGE_ROUTED0(ViewMsg_Move_ACK)
- // Used to instruct the RenderView to send back updates to the intrinsic
- // width.
- IPC_MESSAGE_ROUTED0(ViewMsg_EnableIntrinsicWidthChangedMode)
+ // Used to instruct the RenderView to send back updates to the preferred size.
+ IPC_MESSAGE_ROUTED0(ViewMsg_EnablePreferredSizeChangedMode)
// Used to inform the renderer that the browser has displayed its
// requested notification.
@@ -1135,8 +1134,9 @@ IPC_BEGIN_MESSAGES(ViewHost)
GURL /* referrer */,
WindowOpenDisposition /* disposition */)
- IPC_MESSAGE_ROUTED1(ViewHostMsg_DidContentsPreferredWidthChange,
- int /* pref_width */)
+ // Notify that the preferred size of the content changed.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_DidContentsPreferredSizeChange,
+ gfx::Size /* pref_size */)
// Following message is used to communicate the values received by the
// callback binding the JS to Cpp.
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index dce72c2..d2130c6 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -227,8 +227,7 @@ RenderView::RenderView(RenderThreadBase* render_thread,
popup_notification_visible_(false),
spelling_panel_visible_(false),
delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync),
- preferred_width_(0),
- send_preferred_width_changes_(false),
+ send_preferred_size_changes_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(
notification_provider_(new NotificationProvider(this))),
determine_page_text_after_loading_stops_(false),
@@ -475,8 +474,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
OnExtensionMessageInvoke)
IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
- IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
- OnEnableIntrinsicWidthChangedMode)
+ IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
+ OnEnablePreferredSizeChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateBrowserWindowId,
OnUpdateBrowserWindowId)
@@ -2366,16 +2365,23 @@ void RenderView::didCreateIsolatedScriptContext(WebFrame* frame) {
void RenderView::didChangeContentsSize(WebFrame* frame, const WebSize& size) {
// We don't always want to send the change messages over IPC, only if we've
- // be put in that mode by getting a |ViewMsg_EnableIntrinsicWidthChangedMode|
+ // be put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
// message.
- if (send_preferred_width_changes_) {
+ if (send_preferred_size_changes_) {
// WebCore likes to tell us things have changed even when they haven't, so
- // cache the width and only send the IPC message when we're sure the
- // width is different.
+ // cache the width and height and only send the IPC message when we're sure
+ // they're different.
int width = webview()->mainFrame()->contentsPreferredWidth();
- if (width != preferred_width_) {
- Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
- preferred_width_ = width;
+ if (width != preferred_size_.width() ||
+ size.height != preferred_size_.height()) {
+ preferred_size_.set_width(width);
+
+ // TODO(erikkay) the contents size is not really the same as the
+ // preferred size. It's just the current size. This means that for
+ // height, it will only ever grow, it will never shrink.
+ preferred_size_.set_height(size.height);
+ Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_,
+ preferred_size_));
}
}
}
@@ -3027,8 +3033,8 @@ void RenderView::OnEnableViewSourceMode() {
main_frame->enableViewSourceMode(true);
}
-void RenderView::OnEnableIntrinsicWidthChangedMode() {
- send_preferred_width_changes_ = true;
+void RenderView::OnEnablePreferredSizeChangedMode() {
+ send_preferred_size_changes_ = true;
}
void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index d0808e9..ca7d38e 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -601,7 +601,7 @@ class RenderView : public RenderWidget,
void OnInstallMissingPlugin();
void OnFileChooserResponse(const std::vector<FilePath>& file_names);
void OnEnableViewSourceMode();
- void OnEnableIntrinsicWidthChangedMode();
+ void OnEnablePreferredSizeChangedMode();
void OnSetRendererPrefs(const RendererPreferences& renderer_prefs);
void OnMediaPlayerActionAt(const gfx::Point& location,
const WebKit::WebMediaPlayerAction& action);
@@ -901,12 +901,12 @@ class RenderView : public RenderWidget,
// it's for the selection clipboard.
std::string selection_text_;
- // Cache the preferred width of the page in order to prevent sending the IPC
- // when layout() recomputes it but it doesn't actually change.
- int preferred_width_;
+ // Cache the preferred size of the page in order to prevent sending the IPC
+ // when layout() recomputes but doesn't actually change sizes.
+ gfx::Size preferred_size_;
- // If true, we send IPC messages when the preferred width changes.
- bool send_preferred_width_changes_;
+ // If true, we send IPC messages when |preferred_size_| changes.
+ bool send_preferred_size_changes_;
// The text selection the last time DidChangeSelection got called.
std::string last_selection_;
diff --git a/chrome/test/data/extensions/api_test/popup/chromium.png b/chrome/test/data/extensions/api_test/popup/chromium.png
new file mode 100755
index 0000000..cc9fb60
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/popup/chromium.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/popup/manifest.json b/chrome/test/data/extensions/api_test/popup/manifest.json
new file mode 100755
index 0000000..f353316
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/popup/manifest.json
@@ -0,0 +1,10 @@
+{
+ "name": "Popup tester",
+ "version": "0.1",
+ "description": "apitest for popups",
+ "browser_action": {
+ "name": "grow",
+ "icons": ["chromium.png"],
+ "popup": "popup.html"
+ }
+}
diff --git a/chrome/test/data/extensions/api_test/popup/popup.html b/chrome/test/data/extensions/api_test/popup/popup.html
new file mode 100755
index 0000000..02d6342
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/popup/popup.html
@@ -0,0 +1,44 @@
+<head>
+<script>
+function run_tests() {
+ // Compute the size of the popup.
+ var width = 100;
+ var height = 100;
+ if (localStorage.height) {
+ height = parseInt(localStorage.height);
+ }
+ if (localStorage.width) {
+ width = parseInt(localStorage.width);
+ }
+
+ // Set the div's size.
+ var test = document.getElementById("test");
+ test.style.width = width + "px";
+ test.style.height = height + "px";
+ chrome.test.log("height: " + test.offsetHeight);
+ chrome.test.log("width: " + test.offsetWidth);
+
+ // We should be done. Let the test harness know.
+ //window.setTimeout(chrome.test.notifyPass, 0);
+ chrome.test.notifyPass();
+
+ height += 100;
+ width += 100;
+ localStorage.height = JSON.stringify(height);
+ localStorage.width = JSON.stringify(width);
+}
+</script>
+<style>
+body {
+ padding: 0px;
+ margin: 0px;
+}
+div {
+ padding: 0px;
+ margin: 0px;
+}
+</style>
+</head>
+<body onload="window.setTimeout(run_tests, 0)">
+<div id="test">TEST</div>
+</body>
diff --git a/chrome/test/data/extensions/samples/buildbot/manifest.json b/chrome/test/data/extensions/samples/buildbot/manifest.json
index ea764ef..39f6680 100644
--- a/chrome/test/data/extensions/samples/buildbot/manifest.json
+++ b/chrome/test/data/extensions/samples/buildbot/manifest.json
@@ -12,6 +12,6 @@
"browser_action": {
"name": "Buildbot status",
"icons": ["chromium.png"],
- "popup": { "path": "popup.html", "height": 200 }
+ "popup": "popup.html"
}
}
diff --git a/chrome/test/data/extensions/samples/buildbot/popup.html b/chrome/test/data/extensions/samples/buildbot/popup.html
index 415c061..ca2314a 100755
--- a/chrome/test/data/extensions/samples/buildbot/popup.html
+++ b/chrome/test/data/extensions/samples/buildbot/popup.html
@@ -1,3 +1,4 @@
+<head>
<script>
var botRoot = "http://build.chromium.org/buildbot/waterfall";
//var botRoot = "http://chrome-buildbot.corp.google.com:8010";
@@ -82,24 +83,42 @@ function requestURL(url, callback) {
}
window.onload = function() {
bots = document.getElementById("bots");
- bots.innerHTML = "onload";
- //window.setTimeout(requestUrl(waterfallURL, updateBotList), 10);
- requestURL(waterfallURL, updateBotList);
+
+ // XHR from onload winds up blocking the load, so we put it in a setTimeout.
+ window.setTimeout(requestURL, 0, waterfallURL, updateBotList);
}
+
+function toggle_size() {
+ if (document.body.className == "big") {
+ document.body.className = "small";
+ } else {
+ document.body.className = "big";
+ }
+}
+
</script>
<style>
body {
font: menu;
- width: 200px;
- background-color: #dddddd;
overflow: hidden;
}
+body.big .bot {
+ -webkit-transition: all .5s ease-out;
+ padding-right: 100px;
+}
+
+body.small .bot{
+ -webkit-transition: all .5s ease-out;
+ padding-right: 3px;
+}
+
.bot {
cursor: pointer;
-webkit-border-radius: 5px;
margin-top: 1px;
padding: 3px;
+ white-space: nowrap;
}
.bot:hover {
@@ -144,4 +163,7 @@ body {
border: 1px solid rgb(172, 160, 179);
}
</style>
+</head>
+<body onClick="toggle_size()">
<div id="bots">Loading....</div>
+</body> \ No newline at end of file