summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views')
-rw-r--r--chrome/browser/views/browser_actions_container.cc161
-rw-r--r--chrome/browser/views/browser_actions_container.h31
-rw-r--r--chrome/browser/views/browser_bubble.h10
-rw-r--r--chrome/browser/views/browser_bubble_gtk.cc3
-rw-r--r--chrome/browser/views/browser_bubble_win.cc49
-rw-r--r--chrome/browser/views/extensions/extension_popup.cc78
-rw-r--r--chrome/browser/views/extensions/extension_popup.h58
-rw-r--r--chrome/browser/views/extensions/extension_shelf.cc6
-rw-r--r--chrome/browser/views/extensions/extension_view.cc28
-rw-r--r--chrome/browser/views/extensions/extension_view.h10
10 files changed, 396 insertions, 38 deletions
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index bae129f..88c2b02 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -10,12 +10,13 @@
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/image_loading_tracker.h"
#include "chrome/browser/profile.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/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "views/controls/button/text_button.h"
+#include "views/controls/button/menu_button.h"
// The size of the icon for page actions.
static const int kIconSize = 30;
@@ -29,7 +30,7 @@ static const int kHorizontalPadding = 4;
// The BrowserActionImageView is a specialization of the TextButton class.
// It acts on a ExtensionAction, in this case a BrowserAction and handles
// loading the image for the button asynchronously on the file thread to
-class BrowserActionImageView : public views::TextButton,
+class BrowserActionImageView : public views::MenuButton,
public views::ButtonListener,
public ImageLoadingTracker::Observer,
public NotificationObserver {
@@ -50,6 +51,26 @@ class BrowserActionImageView : public views::TextButton,
const NotificationSource& source,
const NotificationDetails& details);
+ // MenuButton behavior overrides. These methods all default to TextButton
+ // behavior unless this button is a popup. In that case, it uses MenuButton
+ // behavior. MenuButton has the notion of a child popup being shown where the
+ // button will stay in the pushed state until the "menu" (a popup in this
+ // case) is dismissed.
+ virtual bool Activate();
+ virtual bool OnMousePressed(const views::MouseEvent& e);
+ virtual void OnMouseReleased(const views::MouseEvent& e, bool canceled);
+ virtual bool OnKeyReleased(const views::KeyEvent& e);
+ virtual void OnMouseExited(const views::MouseEvent& event);
+
+ // Does this button's action have a popup?
+ virtual bool IsPopup();
+
+ // Notifications when the popup is hidden or shown by the container.
+ virtual void PopupDidShow();
+ virtual void PopupDidHide();
+
+ const ExtensionAction& browser_action() const { return *browser_action_; }
+
private:
// Called to update the display to match the browser action's state.
void OnStateUpdated();
@@ -80,7 +101,7 @@ class BrowserActionImageView : public views::TextButton,
BrowserActionImageView::BrowserActionImageView(
ExtensionAction* browser_action, Extension* extension,
BrowserActionsContainer* panel)
- : TextButton(this, L""),
+ : MenuButton(this, L"", NULL, false),
browser_action_(browser_action),
browser_action_state_(extension->browser_action_state()),
tracker_(NULL),
@@ -113,7 +134,7 @@ BrowserActionImageView::~BrowserActionImageView() {
void BrowserActionImageView::ButtonPressed(
views::Button* sender, const views::Event& event) {
- panel_->OnBrowserActionExecuted(*browser_action_);
+ panel_->OnBrowserActionExecuted(this);
}
void BrowserActionImageView::OnImageLoaded(SkBitmap* image, size_t index) {
@@ -142,12 +163,76 @@ void BrowserActionImageView::Observe(NotificationType type,
}
}
+bool BrowserActionImageView::IsPopup() {
+ return (browser_action_ && !browser_action_->popup_url().is_empty());
+}
+
+bool BrowserActionImageView::Activate() {
+ if (IsPopup()) {
+ panel_->OnBrowserActionExecuted(this);
+
+ // TODO(erikkay): Run a nested modal loop while the mouse is down to
+ // enable menu-like drag-select behavior.
+
+ // The return value of this method is returned via OnMousePressed.
+ // We need to return false here since we're handing off focus to another
+ // widget/view, and true will grab it right back and try to send events
+ // to us.
+ return false;
+ }
+ return true;
+}
+
+bool BrowserActionImageView::OnMousePressed(const views::MouseEvent& e) {
+ if (IsPopup())
+ return MenuButton::OnMousePressed(e);
+ return TextButton::OnMousePressed(e);
+}
+
+void BrowserActionImageView::OnMouseReleased(const views::MouseEvent& e,
+ bool canceled) {
+ if (IsPopup()) {
+ // TODO(erikkay) this never actually gets called (probably because of the
+ // loss of focus).
+ MenuButton::OnMouseReleased(e, canceled);
+ } else {
+ TextButton::OnMouseReleased(e, canceled);
+ }
+}
+
+bool BrowserActionImageView::OnKeyReleased(const views::KeyEvent& e) {
+ if (IsPopup())
+ return MenuButton::OnKeyReleased(e);
+ return TextButton::OnKeyReleased(e);
+}
+
+void BrowserActionImageView::OnMouseExited(const views::MouseEvent& e) {
+ if (IsPopup())
+ MenuButton::OnMouseExited(e);
+ else
+ TextButton::OnMouseExited(e);
+}
+
+void BrowserActionImageView::PopupDidShow() {
+ SetState(views::CustomButton::BS_PUSHED);
+ menu_visible_ = true;
+}
+
+void BrowserActionImageView::PopupDidHide() {
+ SetState(views::CustomButton::BS_NORMAL);
+ menu_visible_ = false;
+}
+
////////////////////////////////////////////////////////////////////////////////
// BrowserActionsContainer
BrowserActionsContainer::BrowserActionsContainer(
Profile* profile, ToolbarView* toolbar)
- : profile_(profile), toolbar_(toolbar) {
+ : profile_(profile),
+ toolbar_(toolbar),
+ popup_(NULL),
+ popup_button_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
ExtensionsService* extension_service = profile->GetExtensionsService();
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
Source<ExtensionsService>(extension_service));
@@ -160,6 +245,7 @@ BrowserActionsContainer::BrowserActionsContainer(
}
BrowserActionsContainer::~BrowserActionsContainer() {
+ HidePopup();
DeleteBrowserActionViews();
}
@@ -201,8 +287,51 @@ void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
toolbar_->Layout();
}
+void BrowserActionsContainer::HidePopup() {
+ if (popup_) {
+ popup_->Hide();
+ popup_->DetachFromBrowser();
+ delete popup_;
+ popup_ = NULL;
+ popup_button_->PopupDidHide();
+ popup_button_ = NULL;
+ return;
+ }
+}
+
void BrowserActionsContainer::OnBrowserActionExecuted(
- const ExtensionAction& browser_action) {
+ BrowserActionImageView* button) {
+ const ExtensionAction& browser_action = button->browser_action();
+
+ // Popups just display. No notification to the extension.
+ // TODO(erikkay): should there be?
+ if (button->IsPopup()) {
+ // If we're showing the same popup, just hide it and return.
+ bool same_showing = popup_ && button == popup_button_;
+
+ // Always hide the current popup, even if it's not the same.
+ // Only one popup should be visible at a time.
+ HidePopup();
+
+ if (same_showing)
+ return;
+
+ gfx::Point origin;
+ View::ConvertPointToWidget(button, &origin);
+ gfx::Rect rect = bounds();
+ rect.set_x(origin.x());
+ rect.set_y(origin.y());
+ popup_ = ExtensionPopup::Show(browser_action.popup_url(),
+ toolbar_->browser(),
+ rect,
+ browser_action.popup_height());
+ popup_->set_delegate(this);
+ popup_button_ = button;
+ popup_button_->PopupDidShow();
+ return;
+ }
+
+ // Otherwise, we send the action to the extension.
int window_id = ExtensionTabUtil::GetWindowId(toolbar_->browser());
ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
profile_, browser_action.extension_id(), window_id);
@@ -235,3 +364,23 @@ void BrowserActionsContainer::Observe(NotificationType type,
NOTREACHED() << L"Received unexpected notification";
}
}
+
+void BrowserActionsContainer::BubbleBrowserWindowMoved(BrowserBubble* bubble) {
+}
+
+void BrowserActionsContainer::BubbleBrowserWindowClosing(
+ BrowserBubble* bubble) {
+ HidePopup();
+}
+
+void BrowserActionsContainer::BubbleGotFocus(BrowserBubble* bubble) {
+}
+
+void BrowserActionsContainer::BubbleLostFocus(BrowserBubble* bubble) {
+ // 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
+ // shown again. To workaround this, we put in a delay.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ task_factory_.NewRunnableMethod(&BrowserActionsContainer::HidePopup));
+}
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index fd83437..178a3a2 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -7,15 +7,19 @@
#include <vector>
+#include "base/task.h"
+#include "chrome/browser/views/browser_bubble.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "views/view.h"
+class BrowserActionImageView;
class ExtensionAction;
+class ExtensionPopup;
class Profile;
class ToolbarView;
namespace views {
-class TextButton;
+class MenuButton;
}
////////////////////////////////////////////////////////////////////////////////
@@ -26,7 +30,8 @@ class TextButton;
//
////////////////////////////////////////////////////////////////////////////////
class BrowserActionsContainer : public views::View,
- public NotificationObserver {
+ public NotificationObserver,
+ public BrowserBubble::Delegate {
public:
BrowserActionsContainer(Profile* profile, ToolbarView* toolbar);
virtual ~BrowserActionsContainer();
@@ -43,7 +48,7 @@ class BrowserActionsContainer : public views::View,
void OnBrowserActionVisibilityChanged();
// Called when the user clicks on the browser action icon.
- void OnBrowserActionExecuted(const ExtensionAction& browser_action);
+ void OnBrowserActionExecuted(BrowserActionImageView* button);
// Overridden from views::View:
virtual gfx::Size GetPreferredSize();
@@ -54,9 +59,18 @@ class BrowserActionsContainer : public views::View,
const NotificationSource& source,
const NotificationDetails& details);
+ // BrowserBubble::Delegate methods.
+ virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble);
+ virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble);
+ virtual void BubbleGotFocus(BrowserBubble* bubble);
+ virtual void BubbleLostFocus(BrowserBubble* bubble);
+
private:
+ // Hide the current popup.
+ void HidePopup();
+
// The vector of browser actions (icons/image buttons for each action).
- std::vector<views::TextButton*> browser_action_views_;
+ std::vector<views::MenuButton*> browser_action_views_;
NotificationRegistrar registrar_;
@@ -65,6 +79,15 @@ class BrowserActionsContainer : public views::View,
// The toolbar that owns us.
ToolbarView* toolbar_;
+ // The current popup and the button it came from. NULL if no popup.
+ ExtensionPopup* popup_;
+
+ // The button that triggered the current popup (just a reference to a button
+ // from browser_action_views_).
+ BrowserActionImageView* popup_button_;
+
+ ScopedRunnableMethodFactory<BrowserActionsContainer> task_factory_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer);
};
diff --git a/chrome/browser/views/browser_bubble.h b/chrome/browser/views/browser_bubble.h
index 1ffacb0..327d4fd 100644
--- a/chrome/browser/views/browser_bubble.h
+++ b/chrome/browser/views/browser_bubble.h
@@ -24,6 +24,12 @@ class BrowserBubble {
// Called with the Browser Window that this bubble is attached to is
// about to close.
virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble) = 0;
+
+ // Called when the bubble became active / got focus.
+ virtual void BubbleGotFocus(BrowserBubble* bubble) {}
+
+ // Called when the bubble became inactive / lost focus.
+ virtual void BubbleLostFocus(BrowserBubble* bubble) {}
};
// Note that the bubble will size itself to the preferred size of |view|.
@@ -54,8 +60,8 @@ class BrowserBubble {
virtual void BrowserWindowClosing();
// Show or hide the bubble.
- void Show();
- void Hide();
+ virtual void Show(bool activate);
+ virtual void Hide();
bool visible() const { return visible_; }
// The contained view.
diff --git a/chrome/browser/views/browser_bubble_gtk.cc b/chrome/browser/views/browser_bubble_gtk.cc
index d73f1df..43a6af3 100644
--- a/chrome/browser/views/browser_bubble_gtk.cc
+++ b/chrome/browser/views/browser_bubble_gtk.cc
@@ -30,9 +30,10 @@ void BrowserBubble::MovePopup(int x, int y, int w, int h) {
pop->SetBounds(gfx::Rect(x, y, w, h));
}
-void BrowserBubble::Show() {
+void BrowserBubble::Show(bool activate) {
if (visible_)
return;
+ // TODO(port) respect activate flag.
views::WidgetGtk* pop = static_cast<views::WidgetGtk*>(popup_);
pop->Show();
visible_ = true;
diff --git a/chrome/browser/views/browser_bubble_win.cc b/chrome/browser/views/browser_bubble_win.cc
index e1a1a06..8cae2da 100644
--- a/chrome/browser/views/browser_bubble_win.cc
+++ b/chrome/browser/views/browser_bubble_win.cc
@@ -6,12 +6,53 @@
#include "app/l10n_util_win.h"
#include "chrome/browser/views/frame/browser_view.h"
+#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"
+class BubbleWidget : public views::WidgetWin
+{
+public:
+ BubbleWidget(BrowserBubble* bubble) : bubble_(bubble), closed_(false) {
+ }
+
+ void Show(bool activate) {
+ if (activate)
+ ShowWindow(SW_SHOW);
+ else
+ views::WidgetWin::Show();
+ }
+
+ void Close() {
+ if (closed_)
+ return;
+ closed_ = true;
+ views::WidgetWin::Close();
+ }
+
+ void OnActivate(UINT action, BOOL minimized, HWND window) {
+ BrowserBubble::Delegate* delegate = bubble_->delegate();
+ if (!delegate)
+ return;
+
+ if (action == WA_INACTIVE && !closed_) {
+ delegate->BubbleLostFocus(bubble_);
+ } else if (action == WA_ACTIVE) {
+ delegate->BubbleGotFocus(bubble_);
+ }
+ }
+
+private:
+ bool closed_;
+ BrowserBubble* bubble_;
+};
+
void BrowserBubble::InitPopup() {
gfx::NativeWindow native_window = frame_->GetWindow()->GetNativeWindow();
- views::WidgetWin* pop = new views::WidgetWin();
+
+ // popup_ is a Widget, but we need to do some WidgetWin stuff first, then
+ // we'll assign it into popup_.
+ views::WidgetWin* pop = new BubbleWidget(this);
pop->set_window_style(WS_POPUP);
#if 0
@@ -38,11 +79,11 @@ void BrowserBubble::MovePopup(int x, int y, int w, int h) {
pop->MoveWindow(x, y, w, h);
}
-void BrowserBubble::Show() {
+void BrowserBubble::Show(bool activate) {
if (visible_)
return;
- views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_);
- pop->Show();
+ BubbleWidget* pop = static_cast<BubbleWidget*>(popup_);
+ pop->Show(activate);
visible_ = true;
}
diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc
new file mode 100644
index 0000000..b938b27
--- /dev/null
+++ b/chrome/browser/views/extensions/extension_popup.cc
@@ -0,0 +1,78 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/extensions/extension_popup.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
+
+ExtensionPopup::ExtensionPopup(ExtensionHost* host,
+ views::Widget* frame,
+ const gfx::Rect& relative_to)
+ : BrowserBubble(host->view(),
+ frame,
+ gfx::Point()),
+ relative_to_(relative_to),
+ extension_host_(host) {
+ registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
+ Source<Profile>(host->profile()));
+}
+
+ExtensionPopup::~ExtensionPopup() {
+}
+
+void ExtensionPopup::Show() {
+ ResizeToView();
+
+ // Anchor on the lower right corner and extend to the left.
+ SetBounds(relative_to_.right() - width(), relative_to_.bottom(),
+ width(), height());
+ BrowserBubble::Show(true);
+}
+
+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();
+ } else {
+ NOTREACHED() << L"Received unexpected notification";
+ }
+}
+
+// static
+ExtensionPopup* ExtensionPopup::Show(const GURL& url, Browser* browser,
+ const gfx::Rect& relative_to,
+ int height) {
+ ExtensionProcessManager* manager =
+ browser->profile()->GetExtensionProcessManager();
+ DCHECK(manager);
+ if (!manager)
+ 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);
+ 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.
+ if (host->did_stop_loading())
+ popup->Show();
+
+ return popup;
+}
diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h
new file mode 100644
index 0000000..cdefc8e
--- /dev/null
+++ b/chrome/browser/views/extensions/extension_popup.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
+#define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
+
+#include "googleurl/src/gurl.h"
+#include "chrome/browser/extensions/extension_host.h"
+#include "chrome/browser/views/browser_bubble.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+class Browser;
+class ExtensionHost;
+
+class ExtensionPopup : public BrowserBubble,
+ public NotificationObserver {
+ public:
+ virtual ~ExtensionPopup();
+
+ // Create and show a popup with |url| positioned below |relative_to| in
+ // |browser| coordinates. This is anchored to the lower right corner of the
+ // rect, extending to the left, just like the wrench and page menus.
+ //
+ // 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);
+
+ ExtensionHost* host() const { return extension_host_.get(); }
+
+ // BrowserBubble overrides.
+ virtual void Show();
+
+ // NotificationObserver overrides.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ ExtensionPopup(ExtensionHost* host,
+ views::Widget* frame,
+ const gfx::Rect& relative_to);
+
+ // The area on the screen that the popup should be positioned relative to.
+ const gfx::Rect relative_to_;
+
+ // The contained host for the view.
+ scoped_ptr<ExtensionHost> extension_host_;
+
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionPopup);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_POPUP_H_
diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc
index eee60a1..a586da32 100644
--- a/chrome/browser/views/extensions/extension_shelf.cc
+++ b/chrome/browser/views/extensions/extension_shelf.cc
@@ -587,7 +587,7 @@ void ExtensionShelf::Toolstrip::ShowWindow() {
LayoutWindow();
if (!window_visible())
- window_->Show();
+ window_->Show(false); // |false| means show, but don't activate.
}
void ExtensionShelf::Toolstrip::DoHideShelfHandle() {
@@ -611,7 +611,6 @@ void ExtensionShelf::Toolstrip::Expand(int height, const GURL& url) {
DCHECK(!expanded_);
expanded_ = true;
- view()->set_is_toolstrip(!expanded_);
ShowWindow();
bool navigate = (!url.is_empty() && url != host_->GetURL());
@@ -638,7 +637,6 @@ void ExtensionShelf::Toolstrip::Expand(int height, const GURL& url) {
void ExtensionShelf::Toolstrip::Collapse(const GURL& url) {
DCHECK(expanded_);
expanded_ = false;
- view()->set_is_toolstrip(!expanded_);
if (window_visible())
mole_animation_->Hide();
@@ -1076,7 +1074,7 @@ gfx::Size ExtensionShelf::LayoutItems(bool compute_bounds_only) {
if (clipped)
pref.set_width(std::max(0, max_x - x));
if (view == toolstrip->view())
- toolstrip->view()->set_is_clipped(clipped);
+ toolstrip->view()->SetIsClipped(clipped);
view->SetBounds(x, y, pref.width(), content_height);
view->Layout();
if (toolstrip->window_visible())
diff --git a/chrome/browser/views/extensions/extension_view.cc b/chrome/browser/views/extensions/extension_view.cc
index 24ce5f1..20fc7b1 100644
--- a/chrome/browser/views/extensions/extension_view.cc
+++ b/chrome/browser/views/extensions/extension_view.cc
@@ -15,7 +15,7 @@
ExtensionView::ExtensionView(ExtensionHost* host, Browser* browser)
: host_(host), browser_(browser),
initialized_(false), pending_preferred_width_(0), container_(NULL),
- did_stop_loading_(false), is_clipped_(false), is_toolstrip_(true) {
+ is_clipped_(false) {
host_->set_view(this);
}
@@ -35,10 +35,17 @@ RenderViewHost* ExtensionView::render_view_host() const {
}
void ExtensionView::DidStopLoading() {
- did_stop_loading_ = true;
ShowIfCompletelyLoaded();
}
+void ExtensionView::SetIsClipped(bool is_clipped) {
+ if (is_clipped_ != is_clipped) {
+ is_clipped_ = is_clipped;
+ if (IsVisible())
+ ShowIfCompletelyLoaded();
+ }
+}
+
void ExtensionView::SetVisible(bool is_visible) {
if (is_visible != IsVisible()) {
NativeViewHost::SetVisible(is_visible);
@@ -96,12 +103,17 @@ void ExtensionView::CreateWidgetHostView() {
}
void ExtensionView::ShowIfCompletelyLoaded() {
- // We wait to show the ExtensionView until it has loaded, our parent has
- // given us a background and css has been inserted into page. These can happen
- // in different orders.
- if (!IsVisible() && host_->did_stop_loading() && render_view_host()->view() &&
- !is_clipped_ && did_stop_loading_ &&
- !render_view_host()->view()->background().empty()) {
+ if (IsVisible() || is_clipped_)
+ return;
+
+ // We wait to show the ExtensionView until it has loaded, and the view has
+ // actually been created. These can happen in different orders.
+ if (host_->did_stop_loading() && initialized_) {
+ // For toolstrips, also wait until our parent has given us a background.
+ if (host_->GetRenderViewType() == ViewType::EXTENSION_TOOLSTRIP &&
+ render_view_host()->view()->background().empty()) {
+ return;
+ }
SetVisible(true);
UpdatePreferredWidth(pending_preferred_width_);
}
diff --git a/chrome/browser/views/extensions/extension_view.h b/chrome/browser/views/extensions/extension_view.h
index fc1ef90..3eceee0 100644
--- a/chrome/browser/views/extensions/extension_view.h
+++ b/chrome/browser/views/extensions/extension_view.h
@@ -37,9 +37,7 @@ class ExtensionView : public views::NativeViewHost {
Extension* extension() const;
RenderViewHost* render_view_host() const;
void DidStopLoading();
- void set_is_clipped(bool is_clipped) { is_clipped_ = is_clipped; }
- bool is_toolstrip() const { return is_toolstrip_; }
- void set_is_toolstrip(bool is) { is_toolstrip_ = is; }
+ void SetIsClipped(bool is_clipped);
// Notification from ExtensionHost.
void UpdatePreferredWidth(int pref_width);
@@ -94,15 +92,9 @@ class ExtensionView : public views::NativeViewHost {
// Note: the view does not own its container.
ExtensionContainer* container_;
- // Whether the RenderView has finished loading.
- bool did_stop_loading_;
-
// Whether this extension view is clipped.
bool is_clipped_;
- // Whether this view is currently displaying in toolstrip mode.
- bool is_toolstrip_;
-
DISALLOW_COPY_AND_ASSIGN(ExtensionView);
};