summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 18:56:04 +0000
committertwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 18:56:04 +0000
commit9e92f7c080cf96b8a96736b89214c77e4c894cc2 (patch)
tree3693e852ed88f156b182b9275123c53b7620563d
parent47a87ca4a7dc35ec539db4c2331ab316c1ad325d (diff)
downloadchromium_src-9e92f7c080cf96b8a96736b89214c77e4c894cc2.zip
chromium_src-9e92f7c080cf96b8a96736b89214c77e4c894cc2.tar.gz
chromium_src-9e92f7c080cf96b8a96736b89214c77e4c894cc2.tar.bz2
Removing the experimental Chrome extension popup API. This API will not be added to the set of available extension APIs.
I also removed some of the plumbing associated with the popup api: - Drop-shadow support removed from BrowserBubble. This had only been supported on Windows. - Removed the ExtensionPopup::PopupChrome type. Only popups from the popup API supported rectangle chrome. - Removed the activate-on-show parameter from ExtensionPopup. This was only used for the popup API. All popups activate on show, by default. - Removed the AddRef/Release magic from ExtensionPopup. The API required these semantics because of the complex, asynchronous lifetime management required by the popup API. See ExtensionPopup::Observer::ExtensionPopupClosed. - Removed unneeded methods from ExtensionPopup::Observer, and ExtensionFunctionDispatcher::Delegate. BUG=None TEST=None Review URL: http://codereview.chromium.org/6334101 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74835 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc4
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h7
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc555
-rw-r--r--chrome/browser/extensions/extension_popup_api.h52
-rw-r--r--chrome/browser/extensions/extension_popup_apitest.cc24
-rw-r--r--chrome/browser/ui/views/browser_actions_container.cc7
-rw-r--r--chrome/browser/ui/views/browser_bubble.cc13
-rw-r--r--chrome/browser/ui/views/browser_bubble.h10
-rw-r--r--chrome/browser/ui/views/browser_bubble_gtk.cc3
-rw-r--r--chrome/browser/ui/views/browser_bubble_win.cc4
-rw-r--r--chrome/browser/ui/views/extensions/extension_popup.cc270
-rw-r--r--chrome/browser/ui/views/extensions/extension_popup.h105
-rw-r--r--chrome/browser/ui/views/location_bar/page_action_image_view.cc4
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/extensions/api/extension_api.json109
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc77
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js74
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_from_infobar/background.html29
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-infobar.html25
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-popup.html22
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_from_infobar/manifest.json8
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/background_page.html10
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui.html307
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup.html19
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_a.html24
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_b.html24
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_dismissal.html67
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_sizing.html112
-rw-r--r--chrome/test/data/extensions/api_test/popup/popup_main/manifest.json8
-rw-r--r--ui/views/focus/focus_manager.cc2
-rw-r--r--views/focus/focus_manager.cc2
32 files changed, 84 insertions, 1896 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index d44c655..7507656 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -35,7 +35,6 @@
#include "chrome/browser/extensions/extension_module.h"
#include "chrome/browser/extensions/extension_omnibox_api.h"
#include "chrome/browser/extensions/extension_page_actions_module.h"
-#include "chrome/browser/extensions/extension_popup_api.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_processes_api.h"
#include "chrome/browser/extensions/extension_proxy_api.h"
@@ -192,9 +191,6 @@ void FactoryRegistry::ResetFunctions() {
// I18N.
RegisterFunction<GetAcceptLanguagesFunction>();
- // Popup API.
- RegisterFunction<PopupShowFunction>();
-
// Processes.
RegisterFunction<GetProcessIdForTabFunction>();
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index 699382f..e87489b 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -40,13 +40,6 @@ class ExtensionFunctionDispatcher {
// if the view is not visible.
virtual gfx::NativeView GetNativeViewOfHost() = 0;
- // Typically, the window is assumed to be the window associated with the
- // result of GetBrowser(). Implementations may override this behavior with
- // this method.
- virtual gfx::NativeWindow GetCustomFrameNativeWindow() {
- return NULL;
- }
-
// Asks the delegate for any relevant TabContents associated with this
// context. For example, the TabContents in which an infobar or
// chrome-extension://<id> URL are being shown. Callers must check for a
diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc
deleted file mode 100644
index 0c3acb2..0000000
--- a/chrome/browser/extensions/extension_popup_api.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-// Copyright (c) 2011 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/extensions/extension_popup_api.h"
-
-#include <string>
-
-#include "base/json/json_writer.h"
-#include "base/string_util.h"
-#include "base/stringprintf.h"
-#include "base/values.h"
-#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_web_ui.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_view_host_delegate.h"
-#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/window_sizer.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/notification_source.h"
-#include "chrome/common/notification_type.h"
-#include "chrome/common/url_constants.h"
-#include "ui/gfx/point.h"
-
-#if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/ui/views/bubble_border.h"
-#include "chrome/browser/ui/views/extensions/extension_popup.h"
-#include "views/view.h"
-#include "views/focus/focus_manager.h"
-#endif // TOOLKIT_VIEWS
-
-namespace extension_popup_module_events {
-
-const char kOnPopupClosed[] = "experimental.popup.onClosed.%d";
-
-} // namespace extension_popup_module_events
-
-namespace {
-
-// Errors.
-const char kBadAnchorArgument[] = "Invalid anchor argument.";
-const char kInvalidURLError[] = "Invalid URL.";
-const char kNotAnExtension[] = "Not an extension view.";
-const char kPopupsDisallowed[] =
- "Popups are only supported from tab-contents views.";
-
-// Keys.
-const char kWidthKey[] = "width";
-const char kHeightKey[] = "height";
-const char kTopKey[] = "top";
-const char kLeftKey[] = "left";
-const char kGiveFocusKey[] = "giveFocus";
-const char kDomAnchorKey[] = "domAnchor";
-const char kBorderStyleKey[] = "borderStyle";
-const char kMaxSizeKey[] = "maxSize";
-
-// chrome enumeration values
-const char kRectangleChrome[] = "rectangle";
-
-#if defined(TOOLKIT_VIEWS)
-// Returns an updated arrow location, conditioned on the type of intersection
-// between the popup window, and the screen. |location| is the current position
-// of the arrow on the popup. |intersection| is the rect representing the
-// intersection between the popup view and its working screen. |popup_rect|
-// is the rect of the popup window in screen space coordinates.
-// The returned location will be horizontally or vertically inverted based on
-// if the popup has been clipped horizontally or vertically.
-BubbleBorder::ArrowLocation ToggleArrowLocation(
- BubbleBorder::ArrowLocation location, const gfx::Rect& intersection,
- const gfx::Rect& popup_rect) {
- // If the popup has been clipped horizontally, flip the right-left position
- // of the arrow.
- if (intersection.right() != popup_rect.right() ||
- intersection.x() != popup_rect.x()) {
- location = BubbleBorder::horizontal_mirror(location);
- }
-
- // If the popup has been clipped vertically, flip the bottom-top position
- // of the arrow.
- if (intersection.y() != popup_rect.y() ||
- intersection.bottom() != popup_rect.bottom()) {
- location = BubbleBorder::vertical_mirror(location);
- }
-
- return location;
-}
-#endif // TOOLKIT_VIEWS
-
-}; // namespace
-
-#if defined(TOOLKIT_VIEWS)
-// ExtensionPopupHost objects implement the environment necessary to host
-// an ExtensionPopup views for the popup api. Its main job is to handle
-// its lifetime and to fire the popup-closed event when the popup is closed.
-// Because the close-on-focus-lost behavior is different from page action
-// and browser action, it also manages its own focus change listening. The
-// difference in close-on-focus-lost is that in the page action and browser
-// action cases, the popup closes when the focus leaves the popup or any of its
-// children. In this case, the popup closes when the focus leaves the popups
-// containing view or any of *its* children.
-class ExtensionPopupHost : public ExtensionPopup::Observer,
- public views::WidgetFocusChangeListener,
- public base::RefCounted<ExtensionPopupHost>,
- public NotificationObserver {
- public:
- // Pass |max_popup_size| to specify the maximal size to which the popup
- // will expand. A width or height of 0 will result in the popup making use
- // of the default max width or height, respectively: ExtensionPopup:kMaxWidth,
- // and ExtensionPopup::kMaxHeight.
- explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher,
- const gfx::Size& max_popup_size)
- : dispatcher_(dispatcher), popup_(NULL), max_popup_size_(max_popup_size) {
- AddRef(); // Balanced in DispatchPopupClosedEvent().
- views::FocusManager::GetWidgetFocusManager()->AddFocusChangeListener(this);
- }
-
- ~ExtensionPopupHost() {
- views::FocusManager::GetWidgetFocusManager()->
- RemoveFocusChangeListener(this);
- }
-
- void set_popup(ExtensionPopup* popup) {
- popup_ = popup;
-
- // Now that a popup has been assigned, listen for subsequent popups being
- // created in the same extension - we want to disallow more than one
- // concurrently displayed popup windows.
- registrar_.Add(
- this,
- NotificationType::EXTENSION_HOST_CREATED,
- Source<ExtensionProcessManager>(
- dispatcher_->profile()->GetExtensionProcessManager()));
-
- registrar_.Add(
- this,
- NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW,
- Source<RenderViewHost>(dispatcher_->render_view_host()));
-
- registrar_.Add(
- this,
- NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED,
- Source<Profile>(dispatcher_->profile()));
- }
-
- // Overridden from ExtensionPopup::Observer
- virtual void ExtensionPopupIsClosing(ExtensionPopup* popup) {
- // Unregister the automation resource routing registered upon host
- // creation.
- AutomationResourceRoutingDelegate* router =
- GetRoutingFromDispatcher(dispatcher_);
- if (router)
- router->UnregisterRenderViewHost(popup_->host()->render_view_host());
- }
-
- virtual void ExtensionPopupClosed(void* popup_token) {
- if (popup_ == popup_token) {
- popup_ = NULL;
- DispatchPopupClosedEvent();
- }
- }
-
- virtual void ExtensionHostCreated(ExtensionHost* host) {
- // Pop-up views should share the same automation routing configuration as
- // their hosting views, so register the RenderViewHost of the pop-up with
- // the AutomationResourceRoutingDelegate interface of the dispatcher.
- AutomationResourceRoutingDelegate* router =
- GetRoutingFromDispatcher(dispatcher_);
- if (router)
- router->RegisterRenderViewHost(host->render_view_host());
-
- // Extension hosts created for popup contents exist in the same tab
- // contents as the ExtensionFunctionDispatcher that requested the popup.
- // For example, '_blank' link navigation should be routed through the tab
- // contents that requested the popup.
- if (dispatcher_ && dispatcher_->delegate()) {
- host->set_associated_tab_contents(
- dispatcher_->delegate()->associated_tab_contents());
- }
- }
-
- virtual void ExtensionPopupCreated(ExtensionPopup* popup) {
- // The popup has been created, but not yet displayed, so install the max
- // size overrides before the first positioning.
- if (max_popup_size_.width())
- popup->set_max_width(max_popup_size_.width());
-
- if (max_popup_size_.height())
- popup->set_max_height(max_popup_size_.height());
- }
-
- virtual void ExtensionPopupResized(ExtensionPopup* popup) {
- // Reposition the location of the arrow on the popup so that the popup
- // better fits on the working monitor.
- gfx::Rect popup_rect = popup->GetOuterBounds();
- if (popup_rect.IsEmpty())
- return;
-
- scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider(
- WindowSizer::CreateDefaultMonitorInfoProvider());
- gfx::Rect monitor_bounds(
- monitor_provider->GetMonitorWorkAreaMatching(popup_rect));
- gfx::Rect intersection = monitor_bounds.Intersect(popup_rect);
-
- // If the popup is totally out of the bounds of the monitor, then toggling
- // the arrow location will not result in an un-clipped window.
- if (intersection.IsEmpty())
- return;
-
- if (!intersection.Equals(popup_rect)) {
- // The popup was clipped by the monitor. Toggle the arrow position
- // to see if that improves visibility. Note: The assignment and
- // re-assignment of the arrow-position will not trigger an intermittent
- // display.
- BubbleBorder::ArrowLocation previous_location = popup->arrow_position();
- BubbleBorder::ArrowLocation flipped_location = ToggleArrowLocation(
- previous_location, intersection, popup_rect);
- popup->SetArrowPosition(flipped_location);
-
- // Double check that toggling the position actually improved the
- // situation - the popup will be contained entirely in its working monitor
- // bounds.
- gfx::Rect flipped_bounds = popup->GetOuterBounds();
- gfx::Rect updated_monitor_bounds =
- monitor_provider->GetMonitorWorkAreaMatching(flipped_bounds);
- if (!updated_monitor_bounds.Contains(flipped_bounds))
- popup->SetArrowPosition(previous_location);
- }
- }
-
- // Overridden from views::WidgetFocusChangeListener
- virtual void NativeFocusWillChange(gfx::NativeView focused_before,
- gfx::NativeView focused_now) {
- // If the popup doesn't exist, then do nothing.
- if (!popup_)
- return;
-
- // If no view is to be focused, then Chrome was deactivated, so hide the
- // popup.
- if (focused_now) {
- // On XP, the focus change handler may be invoked when the delegate has
- // already been revoked.
- // TODO(twiz@chromium.org): Resolve the trigger of this behaviour.
- if (!dispatcher_ || !dispatcher_->delegate())
- return;
-
- gfx::NativeView host_view =
- dispatcher_->delegate()->GetNativeViewOfHost();
-
- // If the widget hosting the popup contains the newly focused view, then
- // don't dismiss the pop-up.
- ExtensionView* view = popup_->host()->view();
- if (view) {
- views::Widget* popup_root_widget = view->GetWidget();
- if (popup_root_widget &&
- popup_root_widget->ContainsNativeView(focused_now))
- return;
- }
-
- // If the widget or RenderWidgetHostView hosting the extension that
- // launched the pop-up is receiving focus, then don't dismiss the popup.
- views::Widget* host_widget =
- views::Widget::GetWidgetFromNativeView(host_view);
- if (host_widget && host_widget->ContainsNativeView(focused_now))
- return;
-
- RenderWidgetHostView* render_host_view =
- RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
- host_view);
- if (render_host_view &&
- render_host_view->ContainsNativeView(focused_now))
- return;
- }
-
- // We are careful here to let the current event loop unwind before
- // causing the popup to be closed.
- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(popup_,
- &ExtensionPopup::Close));
- }
-
- // Overridden from NotificationObserver
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (NotificationType::EXTENSION_HOST_CREATED == type) {
- Details<ExtensionHost> details_host(details);
- // Disallow multiple pop-ups from the same extension, by closing
- // the presently opened popup during construction of any new popups.
- if (ViewType::EXTENSION_POPUP == details_host->GetRenderViewType() &&
- popup_->host()->extension() == details_host->extension() &&
- Details<ExtensionHost>(popup_->host()) != details) {
- popup_->Close();
- }
- } else if (NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW ==
- type) {
- if (Source<RenderViewHost>(dispatcher_->render_view_host()) == source) {
- // If the parent render view is about to be closed, signal closure
- // of the popup.
- popup_->Close();
- }
- } else if (NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED ==
- type) {
- // Popups should not outlive the dispatchers that launched them.
- // Normally, long-lived popups will be dismissed in response to the
- // RENDER_VIEW_WILL_CLOSE_BY_RENDER_VIEW_HOST message. Unfortunately,
- // if the hosting view invokes window.close(), there is no communication
- // back to the browser until the entire view has been torn down, at which
- // time the dispatcher will be invoked.
- // Note: The onClosed event will not be fired, but because the hosting
- // view has already been torn down, it is already too late to process it.
- // TODO(twiz): Add a communication path between the renderer and browser
- // for RenderView closure notifications initiatied within the renderer.
- if (Details<ExtensionFunctionDispatcher>(dispatcher_) == details) {
- dispatcher_ = NULL;
- popup_->Close();
- }
- }
- }
-
- private:
- // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|.
- static AutomationResourceRoutingDelegate*
- GetRoutingFromDispatcher(ExtensionFunctionDispatcher* dispatcher) {
- if (!dispatcher)
- return NULL;
-
- RenderViewHost* render_view_host = dispatcher->render_view_host();
- RenderViewHostDelegate* delegate =
- render_view_host ? render_view_host->delegate() : NULL;
-
- return delegate ? delegate->GetAutomationResourceRoutingDelegate() : NULL;
- }
-
- void DispatchPopupClosedEvent() {
- if (dispatcher_) {
- PopupEventRouter::OnPopupClosed(
- dispatcher_->profile(),
- dispatcher_->render_view_host()->routing_id());
- dispatcher_ = NULL;
- }
- Release(); // Balanced in ctor.
- }
-
- // A pointer to the dispatcher that handled the request that opened this
- // popup view.
- ExtensionFunctionDispatcher* dispatcher_;
-
- // A pointer to the popup.
- ExtensionPopup* popup_;
-
- // The maximal size to which the popup is permitted to expand.
- gfx::Size max_popup_size_;
-
- NotificationRegistrar registrar_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost);
-};
-#endif // TOOLKIT_VIEWS
-
-PopupShowFunction::PopupShowFunction()
-#if defined (TOOLKIT_VIEWS)
- : popup_(NULL)
-#endif
-{}
-
-void PopupShowFunction::Run() {
-#if defined(TOOLKIT_VIEWS)
- if (!RunImpl()) {
- SendResponse(false);
- } else {
- // If the contents of the popup are already available, then immediately
- // send the response. Otherwise wait for the EXTENSION_POPUP_VIEW_READY
- // notification.
- if (popup_->host() && popup_->host()->document_element_available()) {
- SendResponse(true);
- } else {
- AddRef();
- registrar_.Add(this, NotificationType::EXTENSION_POPUP_VIEW_READY,
- NotificationService::AllSources());
- registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED,
- NotificationService::AllSources());
- }
- }
-#else
- SendResponse(false);
-#endif
-}
-
-bool PopupShowFunction::RunImpl() {
- // Popups may only be displayed from TAB_CONTENTS and EXTENSION_INFOBAR.
- ViewType::Type view_type =
- dispatcher()->render_view_host()->delegate()->GetRenderViewType();
- if (ViewType::TAB_CONTENTS != view_type &&
- ViewType::EXTENSION_INFOBAR != view_type) {
- error_ = kPopupsDisallowed;
- return false;
- }
-
- std::string url_string;
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string));
-
- DictionaryValue* show_details = NULL;
- EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &show_details));
-
- DictionaryValue* dom_anchor = NULL;
- EXTENSION_FUNCTION_VALIDATE(show_details->GetDictionary(kDomAnchorKey,
- &dom_anchor));
-
- int dom_top, dom_left;
- EXTENSION_FUNCTION_VALIDATE(dom_anchor->GetInteger(kTopKey,
- &dom_top));
- EXTENSION_FUNCTION_VALIDATE(dom_anchor->GetInteger(kLeftKey,
- &dom_left));
-
- int dom_width, dom_height;
- EXTENSION_FUNCTION_VALIDATE(dom_anchor->GetInteger(kWidthKey,
- &dom_width));
- EXTENSION_FUNCTION_VALIDATE(dom_anchor->GetInteger(kHeightKey,
- &dom_height));
- EXTENSION_FUNCTION_VALIDATE(dom_top >= 0 && dom_left >= 0 &&
- dom_width >= 0 && dom_height >= 0);
-
- // The default behaviour is to give the focus to the pop-up window.
- bool give_focus = true;
- if (show_details->HasKey(kGiveFocusKey)) {
- EXTENSION_FUNCTION_VALIDATE(show_details->GetBoolean(kGiveFocusKey,
- &give_focus));
- }
-
- int max_width = 0;
- int max_height = 0;
- if (show_details->HasKey(kMaxSizeKey)) {
- DictionaryValue* max_size = NULL;
- EXTENSION_FUNCTION_VALIDATE(show_details->GetDictionary(kMaxSizeKey,
- &max_size));
-
- if (max_size->HasKey(kWidthKey))
- EXTENSION_FUNCTION_VALIDATE(max_size->GetInteger(kWidthKey, &max_width));
-
- if (max_size->HasKey(kHeightKey))
- EXTENSION_FUNCTION_VALIDATE(max_size->GetInteger(kHeightKey,
- &max_height));
- }
-
-#if defined(TOOLKIT_VIEWS)
- // The default behaviour is to provide the bubble-chrome to the popup.
- ExtensionPopup::PopupChrome chrome = ExtensionPopup::BUBBLE_CHROME;
- if (show_details->HasKey(kBorderStyleKey)) {
- std::string chrome_string;
- EXTENSION_FUNCTION_VALIDATE(show_details->GetString(kBorderStyleKey,
- &chrome_string));
- if (chrome_string == kRectangleChrome)
- chrome = ExtensionPopup::RECTANGLE_CHROME;
- }
-#endif
-
- GURL url = dispatcher()->url().Resolve(url_string);
- if (!url.is_valid()) {
- error_ = kInvalidURLError;
- return false;
- }
-
- // Disallow non-extension requests, or requests outside of the requesting
- // extension view's extension.
- const std::string& extension_id = url.host();
- if (extension_id != GetExtension()->id() ||
- !url.SchemeIs(chrome::kExtensionScheme)) {
- error_ = kInvalidURLError;
- return false;
- }
-
- gfx::Point origin(dom_left, dom_top);
- if (!dispatcher()->render_view_host()->view()) {
- error_ = kNotAnExtension;
- return false;
- }
-
- gfx::Rect content_bounds =
- dispatcher()->render_view_host()->view()->GetViewBounds();
- origin.Offset(content_bounds.x(), content_bounds.y());
- gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height);
-
- // Get the correct native window to pass to ExtensionPopup.
- // ExtensionFunctionDispatcher::Delegate may provide a custom implementation
- // of this.
- gfx::NativeWindow window =
- dispatcher()->delegate()->GetCustomFrameNativeWindow();
- if (!window)
- window = GetCurrentBrowser()->window()->GetNativeHandle();
-
-#if defined(TOOLKIT_VIEWS)
- BubbleBorder::ArrowLocation arrow_location = BubbleBorder::TOP_LEFT;
-
- // ExtensionPopupHost manages it's own lifetime.
- ExtensionPopupHost* popup_host =
- new ExtensionPopupHost(dispatcher(), gfx::Size(max_width, max_height));
- popup_ = ExtensionPopup::Show(url,
- GetCurrentBrowser(),
- dispatcher()->profile(),
- window,
- rect,
- arrow_location,
- give_focus,
- false, // inspect_with_devtools
- chrome,
- popup_host); // ExtensionPopup::Observer
-
- // popup_host will handle focus change listening and close the popup when
- // focus leaves the containing views hierarchy.
- popup_->set_close_on_lost_focus(false);
- popup_host->set_popup(popup_);
-#endif // defined(TOOLKIT_VIEWS)
-
- return true;
-}
-
-void PopupShowFunction::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
-#if defined(TOOLKIT_VIEWS)
- DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY ||
- type == NotificationType::EXTENSION_HOST_DESTROYED);
- DCHECK(popup_ != NULL);
-
- // Wait for notification that the popup view is ready (and onload has been
- // called), before completing the API call.
- if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY &&
- Details<ExtensionHost>(popup_->host()) == details) {
- SendResponse(true);
- Release(); // Balanced in Run().
- } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED &&
- Details<ExtensionHost>(popup_->host()) == details) {
- // If the host was destroyed, then report failure, and release the remaining
- // reference.
- SendResponse(false);
- Release(); // Balanced in Run().
- }
-#endif // defined(TOOLKIT_VIEWS)
-}
-
-// static
-void PopupEventRouter::OnPopupClosed(Profile* profile,
- int routing_id) {
- std::string full_event_name = base::StringPrintf(
- extension_popup_module_events::kOnPopupClosed,
- routing_id);
-
- profile->GetExtensionEventRouter()->DispatchEventToRenderers(
- full_event_name, base::JSONWriter::kEmptyArray, profile, GURL());
-}
diff --git a/chrome/browser/extensions/extension_popup_api.h b/chrome/browser/extensions/extension_popup_api.h
deleted file mode 100644
index 0b62fe4..0000000
--- a/chrome/browser/extensions/extension_popup_api.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2010 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_EXTENSIONS_EXTENSION_POPUP_API_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_POPUP_API_H_
-#pragma once
-
-#include "chrome/browser/extensions/extension_function.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-
-class Profile;
-class ExtensionPopup;
-
-// This extension function shows a pop-up extension view. It is asynchronous
-// because the callback must be invoked only after the associated render
-// process/view has been created and fully initialized.
-class PopupShowFunction : public AsyncExtensionFunction,
- public NotificationObserver {
- public:
- PopupShowFunction();
-
- virtual void Run();
- virtual bool RunImpl();
- DECLARE_EXTENSION_FUNCTION_NAME("experimental.popup.show")
-
- private:
- // NotificationObserver methods.
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
- NotificationRegistrar registrar_;
-
-#if defined(TOOLKIT_VIEWS)
- // The pop-up view created by this function, saved for access during
- // event notification. The pop-up is not owned by the PopupShowFunction
- // instance.
- ExtensionPopup* popup_;
-#endif
-};
-
-// Event router class for events related to the chrome.popup.* set of APIs.
-class PopupEventRouter {
- public:
- static void OnPopupClosed(Profile* profile,
- int routing_id);
- private:
- DISALLOW_COPY_AND_ASSIGN(PopupEventRouter);
-};
-
-#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_POPUP_API_H_
diff --git a/chrome/browser/extensions/extension_popup_apitest.cc b/chrome/browser/extensions/extension_popup_apitest.cc
deleted file mode 100644
index 232d35b..0000000
--- a/chrome/browser/extensions/extension_popup_apitest.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 "base/command_line.h"
-#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/common/chrome_switches.h"
-
-// TODO(beng): Marking disabled... this change causes this test to fail however
-// twiz@ notes that this test and the support code for it are going
-// away very soon so I don't need to fix it. Yay! >:D
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_Popup) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalExtensionApis);
-
- ASSERT_TRUE(RunExtensionTest("popup/popup_main")) << message_;
-}
-
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupFromInfobar) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalExtensionApis);
-
- ASSERT_TRUE(RunExtensionTest("popup/popup_from_infobar")) << message_;
-}
diff --git a/chrome/browser/ui/views/browser_actions_container.cc b/chrome/browser/ui/views/browser_actions_container.cc
index 77ecd07..9516d73 100644
--- a/chrome/browser/ui/views/browser_actions_container.cc
+++ b/chrome/browser/ui/views/browser_actions_container.cc
@@ -511,13 +511,12 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
gfx::Rect rect = reference_view->bounds();
rect.set_origin(origin);
- gfx::NativeWindow frame_window = browser_->window()->GetNativeHandle();
BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
- popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_,
- browser_->profile(), frame_window, rect, arrow_location, true,
- inspect_with_devtools, ExtensionPopup::BUBBLE_CHROME, this);
+ popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_, rect,
+ arrow_location, inspect_with_devtools,
+ this);
popup_button_ = button;
popup_button_->SetButtonPushed();
}
diff --git a/chrome/browser/ui/views/browser_bubble.cc b/chrome/browser/ui/views/browser_bubble.cc
index bd3c20a..33d5052 100644
--- a/chrome/browser/ui/views/browser_bubble.cc
+++ b/chrome/browser/ui/views/browser_bubble.cc
@@ -24,28 +24,19 @@ BrowserBubbleHost* GetBubbleHostFromFrame(views::Widget* frame) {
window->GetNativeWindow());
DCHECK(bubble_host);
}
-#if defined(OS_WIN)
- // The frame may also be an ExternalTabContainer, which is also capable of
- // hosting BrowserBubbles.
- gfx::NativeView native_view = frame->GetNativeView();
- if (!bubble_host) {
- bubble_host =
- ExternalTabContainer::GetExternalContainerFromNativeWindow(native_view);
- }
-#endif
+
return bubble_host;
}
} // namespace
BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame,
- const gfx::Point& origin, bool drop_shadow)
+ const gfx::Point& origin)
: frame_(frame),
view_(view),
visible_(false),
delegate_(NULL),
attached_(false),
- drop_shadow_enabled_(drop_shadow),
bubble_host_(GetBubbleHostFromFrame(frame)) {
gfx::Size size = view->GetPreferredSize();
bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height());
diff --git a/chrome/browser/ui/views/browser_bubble.h b/chrome/browser/ui/views/browser_bubble.h
index 8cc63a3..8bb433f 100644
--- a/chrome/browser/ui/views/browser_bubble.h
+++ b/chrome/browser/ui/views/browser_bubble.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -40,10 +40,9 @@ class BrowserBubble {
// Note that the bubble will size itself to the preferred size of |view|.
// |view| is the embedded view, |frame| is widget that the bubble is being
// positioned relative to, |origin| is the location that the bubble will
- // be positioned relative to |frame|. Pass true through |drop_shadow| to
- // surround the bubble widget with a drop-shadow.
+ // be positioned relative to |frame|.
BrowserBubble(views::View* view, views::Widget* frame,
- const gfx::Point& origin, bool drop_shadow);
+ const gfx::Point& origin);
virtual ~BrowserBubble();
// Call manually if you need to detach the bubble from tracking the browser's
@@ -119,9 +118,6 @@ class BrowserBubble {
// Is the bubble attached to a Browser window.
bool attached_;
- // Does the bubble have a drop-shadow.
- bool drop_shadow_enabled_;
-
// Non-owning pointer to the host of this bubble.
BrowserBubbleHost* bubble_host_;
diff --git a/chrome/browser/ui/views/browser_bubble_gtk.cc b/chrome/browser/ui/views/browser_bubble_gtk.cc
index 1b45997..8932731 100644
--- a/chrome/browser/ui/views/browser_bubble_gtk.cc
+++ b/chrome/browser/ui/views/browser_bubble_gtk.cc
@@ -84,9 +84,6 @@ class BubbleWidget : public views::WidgetGtk {
void BrowserBubble::InitPopup() {
// TODO(port)
- DCHECK(!drop_shadow_enabled_) <<
- "Drop shadows not supported on GTK browser bubbles.";
-
views::WidgetGtk* pop = new BubbleWidget(this);
pop->SetOpacity(0xFF);
pop->make_transient_to_parent();
diff --git a/chrome/browser/ui/views/browser_bubble_win.cc b/chrome/browser/ui/views/browser_bubble_win.cc
index 8f85c2c..6f1d8dc 100644
--- a/chrome/browser/ui/views/browser_bubble_win.cc
+++ b/chrome/browser/ui/views/browser_bubble_win.cc
@@ -98,10 +98,6 @@ void BrowserBubble::InitPopup() {
// then we'll assign it into popup_.
views::NativeWidgetWin* pop = new BubbleWidget(this);
- // Enable the drop-shadow through the native windows drop-shadow support.
- if (drop_shadow_enabled_)
- pop->set_initial_class_style(CS_DROPSHADOW | pop->initial_class_style());
-
pop->Init(frame_->GetNativeView(), bounds_);
pop->SetContentsView(view_);
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc
index bfd56c8..15a6a26 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.cc
+++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -14,15 +14,12 @@
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/window_sizer.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"
-#include "third_party/skia/include/core/SkColor.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"
@@ -38,10 +35,9 @@
using std::vector;
using views::Widget;
-// The minimum, and default maximum dimensions of the popup.
+// The minimum/maximum dimensions of the popup.
// The minimum is just a little larger than the size of the button itself.
-// The default maximum is an arbitrary number that should be smaller than most
-// screens.
+// The maximum is an arbitrary number that should be smaller than most screens.
const int ExtensionPopup::kMinWidth = 25;
const int ExtensionPopup::kMinHeight = 25;
const int ExtensionPopup::kMaxWidth = 800;
@@ -60,31 +56,20 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show,
bool inspect_with_devtools,
- PopupChrome chrome,
Observer* observer)
: BrowserBubble(host->view(),
frame,
- gfx::Point(),
- RECTANGLE_CHROME == chrome), // If no bubble chrome is to
- // be displayed, then enable a
- // drop-shadow on the bubble
- // widget.
+ gfx::Point()),
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),
- max_size_(kMaxWidth, kMaxHeight),
- observer_(observer),
- anchor_position_(arrow_location),
- instance_lifetime_(new InternalRefCounter()){
+ observer_(observer) {
AddRef(); // Balanced in Close();
set_delegate(this);
host->view()->SetContainer(this);
@@ -108,67 +93,47 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host,
relative_to_.set_origin(origin);
// The bubble chrome requires a separate window, so construct it here.
- if (BUBBLE_CHROME == popup_chrome_) {
- gfx::NativeView native_window = frame->GetNativeView();
+ gfx::NativeView native_window = frame->GetNativeView();
#if defined(OS_LINUX)
- border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
- static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
- static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
+ border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
+ static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
+ static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
#else
- border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
- Widget::NotAcceptEvents,
- Widget::DeleteOnDestroy,
- Widget::MirrorOriginInRTL);
+ border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
+ Widget::NotAcceptEvents,
+ Widget::DeleteOnDestroy,
+ Widget::MirrorOriginInRTL);
#endif
- border_widget_->Init(native_window, bounds());
+ border_widget_->Init(native_window, bounds());
#if defined(OS_CHROMEOS)
- {
- vector<int> params;
- params.push_back(0); // don't show while screen is locked
- chromeos::WmIpc::instance()->SetWindowType(
- border_widget_->GetNativeView(),
- chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE,
- &params);
- }
-#endif
- border_ = new BubbleBorder(arrow_location);
- border_view_ = new views::View;
- border_view_->set_background(new BubbleBackground(border_));
-
- border_view_->set_border(border_);
- border_widget_->SetContentsView(border_view_);
- // Ensure that the popup contents are always displayed ontop of the border
- // widget.
- border_widget_->MoveAbove(popup_);
- } else {
- // Otherwise simply set a black-border on the view containing the popup
- // extension view.
- views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth,
- SK_ColorBLACK);
- view()->set_border(border);
+ {
+ vector<int> params;
+ params.push_back(0); // don't show while screen is locked
+ chromeos::WmIpc::instance()->SetWindowType(
+ border_widget_->GetNativeView(),
+ chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE,
+ &params);
}
+#endif
+ border_ = new BubbleBorder(arrow_location);
+ border_view_ = new views::View;
+ border_view_->set_background(new BubbleBackground(border_));
+
+ border_view_->set_border(border_);
+ border_widget_->SetContentsView(border_view_);
+ // Ensure that the popup contents are always displayed ontop of the border
+ // widget.
+ border_widget_->MoveAbove(popup_);
}
ExtensionPopup::~ExtensionPopup() {
// The widget is set to delete on destroy, so no leak here.
- if (border_widget_)
- border_widget_->Close();
-}
-
-void ExtensionPopup::SetArrowPosition(
- BubbleBorder::ArrowLocation arrow_location) {
- DCHECK_NE(BubbleBorder::NONE, arrow_location) <<
- "Extension popups must be positioned relative to an arrow.";
-
- anchor_position_ = arrow_location;
- if (border_)
- border_->set_arrow_location(anchor_position_);
+ border_widget_->Close();
}
void ExtensionPopup::Hide() {
BrowserBubble::Hide();
- if (border_widget_)
- border_widget_->Hide();
+ border_widget_->Hide();
}
void ExtensionPopup::Show(bool activate) {
@@ -176,46 +141,43 @@ void ExtensionPopup::Show(bool activate) {
return;
#if defined(OS_WIN)
- if (frame_->GetWindow())
- frame_->GetWindow()->DisableInactiveRendering();
+ frame_->GetWindow()->DisableInactiveRendering();
#endif
ResizeToView();
// Show the border first, then the popup overlaid on top.
- if (border_widget_)
- border_widget_->Show();
+ border_widget_->Show();
BrowserBubble::Show(activate);
}
void ExtensionPopup::ResizeToView() {
- if (observer_)
- observer_->ExtensionPopupResized(this);
-
- gfx::Rect rect = GetOuterBounds();
-
+ // We'll be sizing ourselves to this size shortly, but wait until we
+ // know our position to do it.
+ gfx::Size new_size = view()->size();
+
+ // 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
+ // contents size to compensate.
+ int corner_inset = BubbleBorder::GetCornerRadius() / 2;
+ gfx::Size adjusted_size = new_size;
+ adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset);
+ gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size);
+ border_widget_->SetBounds(rect);
+
+ // Now calculate the inner bounds. This is a bit more convoluted than
+ // it should be because BrowserBubble coordinates are in Browser coordinates
+ // while |rect| is in screen coordinates.
+ gfx::Insets border_insets;
+ border_->GetInsets(&border_insets);
gfx::Point origin = rect.origin();
views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);
- if (border_widget_) {
- // Set the bubble-chrome widget according to the outer bounds of the entire
- // popup.
- border_widget_->SetBounds(rect);
-
- // Now calculate the inner bounds. This is a bit more convoluted than
- // it should be because BrowserBubble coordinates are in Browser coordinates
- // while |rect| is in screen coordinates.
- gfx::Insets border_insets;
- border_->GetInsets(&border_insets);
-
- origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius);
- origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius);
+ origin.set_x(origin.x() + border_insets.left() + corner_inset);
+ origin.set_y(origin.y() + border_insets.top() + corner_inset);
- gfx::Size new_size = view()->size();
- SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
- } else {
- SetBounds(origin.x(), origin.y(), rect.width(), rect.height());
- }
+ SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
}
void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) {
@@ -259,7 +221,7 @@ void ExtensionPopup::Observe(NotificationType type,
// 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_);
+ Show(true);
if (inspect_with_devtools_) {
// Listen for the the devtools window closing.
@@ -299,121 +261,38 @@ void ExtensionPopup::Observe(NotificationType type,
void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
// Constrain the size to popup min/max.
gfx::Size sz = view->GetPreferredSize();
-
- // Enforce that the popup never resizes to larger than the working monitor
- // bounds.
- scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider(
- WindowSizer::CreateDefaultMonitorInfoProvider());
- gfx::Rect monitor_bounds(
- monitor_provider->GetMonitorWorkAreaMatching(relative_to_));
-
- int max_width = std::min(max_size_.width(), monitor_bounds.width());
- int max_height = std::min(max_size_.height(), monitor_bounds.height());
view->SetBounds(view->x(), view->y(),
- std::max(kMinWidth, std::min(max_width, sz.width())),
- std::max(kMinHeight, std::min(max_height, sz.height())));
-
- // If popup_chrome_ == RECTANGLE_CHROME, the border is drawn in the client
- // area of the ExtensionView, rather than in a window which sits behind it.
- // In this case, the actual size of the view must be enlarged so that the
- // web contents portion of the view gets its full PreferredSize area.
- if (view->border()) {
- gfx::Insets border_insets;
- view->border()->GetInsets(&border_insets);
-
- gfx::Rect bounds(view->bounds());
- gfx::Size size(bounds.size());
- size.Enlarge(border_insets.width(), border_insets.height());
- view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height());
- }
+ std::max(kMinWidth, std::min(kMaxWidth, sz.width())),
+ std::max(kMinHeight, std::min(kMaxHeight, sz.height())));
ResizeToView();
}
-gfx::Rect ExtensionPopup::GetOuterBounds() const {
- gfx::Rect relative_rect = relative_to_;
- gfx::Point origin = relative_rect.origin();
- views::View::ConvertPointToScreen(frame_->GetRootView(), &origin);
- relative_rect.set_origin(origin);
-
- gfx::Size contents_size = view()->size();
-
- // If the popup has a bubble-chrome, then let the BubbleBorder compute
- // the bounds.
- if (BUBBLE_CHROME == popup_chrome_) {
- // 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 contents size to compensate.
- contents_size.Enlarge(2 * kPopupBubbleCornerRadius,
- 2 * kPopupBubbleCornerRadius);
- return border_->GetBounds(relative_rect, contents_size);
- }
-
- // Position the bounds according to the location of the |anchor_position_|.
- int y;
- if (BubbleBorder::is_arrow_on_top(anchor_position_))
- y = relative_rect.bottom();
- else
- y = relative_rect.y() - contents_size.height();
-
- int x;
- if (BubbleBorder::is_arrow_on_left(anchor_position_))
- x = relative_rect.x();
- else
- // Note that if the arrow is on the right, that the x position of the popup
- // is assigned so that the rightmost edge of the popup is aligned with the
- // rightmost edge of the relative region.
- x = relative_rect.right() - contents_size.width();
-
- return gfx::Rect(x, y, contents_size.width(), contents_size.height());
-}
-
// static
ExtensionPopup* 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,
bool inspect_with_devtools,
- PopupChrome chrome,
Observer* observer) {
- DCHECK(profile);
- DCHECK(frame_window);
- ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
+ ExtensionProcessManager* manager =
+ browser->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);
- if (observer)
- observer->ExtensionHostCreated(host);
-
- ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
- arrow_location, activate_on_show,
- inspect_with_devtools, chrome,
- observer);
-
- if (observer)
- observer->ExtensionPopupCreated(popup);
+ views::Widget* frame = BrowserView::GetBrowserViewForNativeWindow(
+ browser->window()->GetNativeHandle())->GetWidget();
+ ExtensionPopup* popup = new ExtensionPopup(host, frame, relative_to,
+ arrow_location,
+ inspect_with_devtools, 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.
if (host->did_stop_loading())
- popup->Show(activate_on_show);
+ popup->Show(true);
return popup;
}
@@ -429,18 +308,3 @@ void ExtensionPopup::Close() {
Release(); // Balanced in ctor.
}
-
-void ExtensionPopup::Release() {
- bool final_release = instance_lifetime_->HasOneRef();
- instance_lifetime_->Release();
- if (final_release) {
- DCHECK(closing_) << "ExtensionPopup to be destroyed before being closed.";
- ExtensionPopup::Observer* observer = observer_;
- delete this;
-
- // |this| is passed only as a 'cookie'. The observer API explicitly takes a
- // void* argument to emphasize this.
- if (observer)
- observer->ExtensionPopupClosed(this);
- }
-}
diff --git a/chrome/browser/ui/views/extensions/extension_popup.h b/chrome/browser/ui/views/extensions/extension_popup.h
index 1a831f2..2b5870d 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.h
+++ b/chrome/browser/ui/views/extensions/extension_popup.h
@@ -6,14 +6,13 @@
#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
#pragma once
+#include "base/ref_counted.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/ui/views/browser_bubble.h"
#include "chrome/browser/ui/views/bubble_border.h"
#include "chrome/browser/ui/views/extensions/extension_view.h"
#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
#include "googleurl/src/gurl.h"
-#include "ui/gfx/native_widget_types.h"
class Browser;
@@ -26,8 +25,9 @@ class Widget;
class ExtensionPopup : public BrowserBubble,
public BrowserBubble::Delegate,
+ public ExtensionView::Container,
public NotificationObserver,
- public ExtensionView::Container {
+ public base::RefCounted<ExtensionPopup> {
public:
// Observer to ExtensionPopup events.
class Observer {
@@ -36,32 +36,6 @@ class ExtensionPopup : public BrowserBubble,
// is ref-counted, and thus will be released shortly after
// making this delegate call.
virtual void ExtensionPopupIsClosing(ExtensionPopup* popup) {}
-
- // Called after the ExtensionPopup has been closed and deleted.
- // |popup_token| is the address of the deleted ExtensionPopup.
- virtual void ExtensionPopupClosed(void* popup_token) {}
-
- // Called when the ExtensionHost is first created for the pop-up view.
- // Note that this is invoked BEFORE the ExtensionPopup is created, and can
- // be used to provide extra configuration of the host before it is pushed
- // into the popup. An example use is for automation resource routing in
- // Chrome-Frame. See extension_popup_api.cc.
- virtual void ExtensionHostCreated(ExtensionHost* host) {}
-
- // Called immediately after a popup is created, but before the hosted
- // extension has loaded and before the popup has been displayed. Use to
- // finalize configuration of |popup|.
- virtual void ExtensionPopupCreated(ExtensionPopup* popup) {}
-
- // Called when the ExtensionPopup is resized. Note that the popup may have
- // an empty bounds, if a popup is repositioned before the hosted content
- // has loaded.
- virtual void ExtensionPopupResized(ExtensionPopup* popup) {}
- };
-
- enum PopupChrome {
- BUBBLE_CHROME,
- RECTANGLE_CHROME
};
virtual ~ExtensionPopup();
@@ -70,46 +44,22 @@ class ExtensionPopup : public BrowserBubble,
// 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.
// If |arrow_location| is BOTTOM_*, then the popup 'pops up', otherwise
// the popup 'drops down'.
- // Pass |activate_on_show| as true to activate the popup window.
// Pass |inspect_with_devtools| as true to pin the popup open and show the
// devtools window for it.
- // The |chrome| argument controls the chrome that surrounds the pop-up.
- // Passing BUBBLE_CHROME will give the pop-up a bubble-like appearance,
- // including the arrow mentioned above. Passing RECTANGLE_CHROME will give
- // the popup a rectangular, black border with a drop-shadow with no arrow.
- // The positioning of the popup is still governed by the arrow-location
- // parameter.
- //
// 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,
bool inspect_with_devtools,
- PopupChrome chrome,
Observer* observer);
- // Assigns the maximal width and height, respectively, to which the popup
- // may expand. If these routines are not called, the popup will resize to
- // no larger than |kMaxWidth| x |kMaxHeight|. Note that the popup will
- // never expand to larger than the dimensions of the screen.
- void set_max_width(int width) { max_size_.set_width(width); }
- void set_max_height(int height) { max_size_.set_height(height); }
-
- // Closes the ExtensionPopup (this will cause the delegate
- // ExtensionPopupIsClosing and ExtensionPopupClosed to fire.
+ // Closes the ExtensionPopup.
void Close();
// Some clients wish to do their own custom focus change management. If this
@@ -121,18 +71,6 @@ class ExtensionPopup : public BrowserBubble,
ExtensionHost* host() const { return extension_host_.get(); }
- // Assigns the arrow location of the popup view, and updates the popup
- // border widget, if necessary.
- void SetArrowPosition(BubbleBorder::ArrowLocation arrow_location);
- BubbleBorder::ArrowLocation arrow_position() const {
- return anchor_position_;
- }
-
- // Gives the desired bounds (in screen coordinates) given the rect to point
- // to and the size of the contained contents. Includes all of the
- // border-chrome surrounding the pop-up as well.
- gfx::Rect GetOuterBounds() const;
-
// BrowserBubble overrides.
virtual void Hide();
virtual void Show(bool activate);
@@ -155,18 +93,6 @@ class ExtensionPopup : public BrowserBubble,
virtual void OnExtensionMouseLeave(ExtensionView* view) { }
virtual void OnExtensionPreferredSizeChanged(ExtensionView* view);
- // Export the refrence-counted interface required for use as template
- // arguments for RefCounted. ExtensionPopup does not inherit from RefCounted
- // because it must override the behaviour of Release.
- void AddRef() { instance_lifetime_->AddRef(); }
- static bool ImplementsThreadSafeReferenceCounting() {
- return InternalRefCounter::ImplementsThreadSafeReferenceCounting();
- }
-
- // Implements the standard RefCounted<T>::Release behaviour, except
- // signals Observer::ExtensionPopupClosed after final release.
- void Release();
-
// The min/max height of popups.
static const int kMinWidth;
static const int kMinHeight;
@@ -178,9 +104,7 @@ class ExtensionPopup : public BrowserBubble,
views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
- bool activate_on_show,
bool inspect_with_devtools,
- PopupChrome chrome,
Observer* observer);
// The area on the screen that the popup should be positioned relative to.
@@ -189,9 +113,6 @@ class ExtensionPopup : public BrowserBubble,
// The contained host for the view.
scoped_ptr<ExtensionHost> extension_host_;
- // Flag used to indicate if the pop-up should be activated upon first display.
- bool activate_on_show_;
-
// Flag used to indicate if the pop-up should open a devtools window once
// it is shown inspecting it.
bool inspect_with_devtools_;
@@ -212,27 +133,9 @@ class ExtensionPopup : public BrowserBubble,
BubbleBorder* border_;
views::View* border_view_;
- // The type of chrome associated with the popup window.
- PopupChrome popup_chrome_;
-
- // The maximal size to which the popup may expand.
- gfx::Size max_size_;
-
// The observer of this popup.
Observer* observer_;
- // A cached copy of the arrow-position for the bubble chrome.
- // If a black-border was requested, we still need this value to determine
- // the position of the pop-up in relation to |relative_to_|.
- BubbleBorder::ArrowLocation anchor_position_;
-
- // ExtensionPopup's lifetime is managed via reference counting, but it does
- // not expose the RefCounted interface. Instead, the lifetime is tied to
- // this member variable.
- class InternalRefCounter : public base::RefCounted<InternalRefCounter> {
- };
- InternalRefCounter* instance_lifetime_;
-
DISALLOW_COPY_AND_ASSIGN(ExtensionPopup);
};
diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.cc b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
index bcfe51a..1e7ca9a 100644
--- a/chrome/browser/ui/views/location_bar/page_action_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
@@ -89,13 +89,9 @@ void PageActionImageView::ExecuteAction(int button,
popup_ = ExtensionPopup::Show(
page_action_->GetPopupUrl(current_tab_id_),
browser,
- browser->profile(),
- browser->window()->GetNativeHandle(),
screen_bounds,
arrow_location,
- true, // Activate the popup window.
inspect_with_devtools,
- ExtensionPopup::BUBBLE_CHROME,
this); // ExtensionPopup::Observer
} else {
ExtensionService* service = profile_->GetExtensionService();
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 9e1e464..6149067 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1154,8 +1154,6 @@
'browser/extensions/extension_page_actions_module.h',
'browser/extensions/extension_page_actions_module_constants.cc',
'browser/extensions/extension_page_actions_module_constants.h',
- 'browser/extensions/extension_popup_api.cc',
- 'browser/extensions/extension_popup_api.h',
'browser/extensions/extension_pref_store.cc',
'browser/extensions/extension_pref_store.h',
'browser/extensions/extension_pref_value_map.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index b20a8bf..f8ab47c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2206,7 +2206,6 @@
'browser/extensions/extension_module_apitest.cc',
'browser/extensions/extension_omnibox_apitest.cc',
'browser/extensions/extension_override_apitest.cc',
- 'browser/extensions/extension_popup_apitest.cc',
'browser/extensions/extension_proxy_apitest.cc',
'browser/extensions/extension_processes_apitest.cc',
'browser/extensions/extension_resource_request_policy_apitest.cc',
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index e19bad7..2662cde 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -472,27 +472,6 @@
]
},
{
- "namespace": "experimental.extension",
- "nodoc": true,
- "types": [],
- "functions": [
- {
- "name": "getPopupView",
- "type": "function",
- "description": "Returns a reference to the JavaScript 'window' object of the popup view. Returns undefined if no popup presently shown.",
- "parameters": [],
- "returns": {
- "type": "object",
- "isInstanceOf": "DOMWindow",
- "properties": {},
- "additionalProperties": { "type": "any" },
- "optional": true
- }
- }
- ],
- "events": []
- },
- {
"namespace": "experimental.tts",
"functions": [
{
@@ -2405,94 +2384,6 @@
"events": []
},
{
- "namespace": "experimental.popup",
- "nodoc": true,
- "types": [],
- "functions": [
- {
- "name": "show",
- "type": "function",
- "description": "Displays a pop-up window hosting an extension view.",
- "parameters": [
- {
- "type": "string",
- "name": "url",
- "description": "The URL of the contents to which the pop-up will be navigated."
- },
- {
- "type": "object",
- "name": "showDetails",
- "properties": {
- "relativeTo": {
- "type": "object",
- "properties": {},
- "additionalProperties": { "type": "any" },
- "isInstanceOf": "HTMLElement",
- "description": "A HTML DOM object to which the pop-up's position will be made relative."
- },
- "giveFocus": {
- "type": "boolean",
- "description": "Pass true to give the focus to the popup window. The default behaviour is true.",
- "optional": true
- },
- "borderStyle": {
- "type": "string",
- "description": "Pass 'bubble' to give the pop-up window a bubble-chrome border, including an arrow pointing at the relative-to point. Pass 'rectangle' to give the pop-up a rectangular black border with drop-shadow. Default behaviour is to pass 'bubble'.",
- "optional": true,
- "enum": ["bubble", "rectangle"]
- },
- "maxSize": {
- "type": "object",
- "optional": true,
- "properties": {
- "width": {
- "type": "integer",
- "description": "The maximal width to which the popup will resize. If not present, the popup will be no wider than 800 pixels. The popup will widen to no larger than the minimum of the width parameter and the width of the screen.",
- "optional": true,
- "minimum": 32
- },
- "height": {
- "type": "integer",
- "description": "The maximal height to which the popup will resize. If not present, the popup will be no taller than 600 pixels. The popup will grow to no taller than than the minimum of the height parameter and the width of the screen.",
- "optional": true,
- "minimum": 32
- }
- }
- }
- }
- },
- {
- "type": "function",
- "name": "callback",
- "optional": true,
- "parameters": []
- }
- ]
- },
- {
- "name": "getParentWindow",
- "type": "function",
- "description": "Returns a reference to the JavaScript 'window' object of the extension view that launched the popup. Returns undefined if called outside of a popup window.",
- "parameters": [],
- "returns": {
- "type": "object",
- "isInstanceOf": "DOMWindow",
- "properties": {},
- "additionalProperties": { "type": "any" },
- "optional": true
- }
- }
- ],
- "events": [
- {
- "name": "onClosed",
- "type": "function",
- "description": "Fired when the popup view is closed.",
- "parameters": []
- }
- ]
- },
- {
"namespace": "experimental.bookmarkManager",
"nodoc": true,
"types": [
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 42c980d..923ddf6 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -130,20 +130,9 @@ class ExtensionViewAccumulator : public RenderViewVisitor {
if (extension_id != extension_id_)
return true;
- // If we are searching for a pop-up, it may be the case that the pop-up
- // is not attached to a browser window instance. (It is hosted in a
- // ExternalTabContainer.) If so, then bypass validation of
- // same-browser-window origin.
- // TODO(twiz): The browser window id of the views visited should always
- // match that of the arguments to the accumulator.
- // See bug: http://crbug.com/29646
- if (!(view_type_ == ViewType::EXTENSION_POPUP &&
- render_view->browser_window_id() ==
- extension_misc::kUnknownWindowId)) {
- if (browser_window_id_ != extension_misc::kUnknownWindowId &&
- render_view->browser_window_id() != browser_window_id_) {
- return true;
- }
+ if (browser_window_id_ != extension_misc::kUnknownWindowId &&
+ render_view->browser_window_id() != browser_window_id_) {
+ return true;
}
v8::Local<v8::Context> context =
@@ -236,10 +225,6 @@ class ExtensionImpl : public ExtensionBase {
return v8::FunctionTemplate::New(StartRequest);
} else if (name->Equals(v8::String::New("GetRenderViewId"))) {
return v8::FunctionTemplate::New(GetRenderViewId);
- } else if (name->Equals(v8::String::New("GetPopupView"))) {
- return v8::FunctionTemplate::New(GetPopupView);
- } else if (name->Equals(v8::String::New("GetPopupParentWindow"))) {
- return v8::FunctionTemplate::New(GetPopupParentWindow);
} else if (name->Equals(v8::String::New("SetIconCommon"))) {
return v8::FunctionTemplate::New(SetIconCommon);
} else if (name->Equals(v8::String::New("IsExtensionProcess"))) {
@@ -257,62 +242,6 @@ class ExtensionImpl : public ExtensionBase {
return v8::String::New(GetStringResource(IDR_EXTENSION_API_JSON));
}
- static v8::Handle<v8::Value> PopupViewFinder(
- const v8::Arguments& args,
- ViewType::Type viewtype_to_find) {
- // TODO(twiz) Correct the logic that ties the ownership of the pop-up view
- // to the hosting view. At the moment we assume that there may only be
- // a single pop-up view for a given extension. By doing so, we can find
- // the pop-up view by simply searching for the only pop-up view present.
- // We also assume that if the current view is a pop-up, we can find the
- // hosting view by searching for a tab contents view.
- if (args.Length() != 0)
- return v8::Undefined();
-
- if (viewtype_to_find != ViewType::EXTENSION_POPUP &&
- viewtype_to_find != ViewType::EXTENSION_INFOBAR &&
- viewtype_to_find != ViewType::TAB_CONTENTS) {
- NOTREACHED() << "Requesting invalid view type.";
- }
-
- // Disallow searching for the same view type as the current view:
- // Popups can only look for hosts, and hosts can only look for popups.
- RenderView* render_view = bindings_utils::GetRenderViewForCurrentContext();
- if (!render_view ||
- render_view->view_type() == viewtype_to_find) {
- return v8::Undefined();
- }
-
- int browser_window_id = render_view->browser_window_id();
- std::string extension_id = ExtensionIdForCurrentContext();
- if (extension_id.empty())
- return v8::Undefined();
-
- ExtensionViewAccumulator popup_matcher(extension_id,
- browser_window_id,
- viewtype_to_find);
- RenderView::ForEach(&popup_matcher);
-
- if (0 == popup_matcher.views()->Length())
- return v8::Undefined();
- DCHECK(1 == popup_matcher.views()->Length());
-
- // Return the first view found.
- return popup_matcher.views()->Get(v8::Integer::New(0));
- }
-
- static v8::Handle<v8::Value> GetPopupView(const v8::Arguments& args) {
- return PopupViewFinder(args, ViewType::EXTENSION_POPUP);
- }
-
- static v8::Handle<v8::Value> GetPopupParentWindow(const v8::Arguments& args) {
- v8::Handle<v8::Value> view = PopupViewFinder(args, ViewType::TAB_CONTENTS);
- if (view == v8::Undefined()) {
- view = PopupViewFinder(args, ViewType::EXTENSION_INFOBAR);
- }
- return view;
- }
-
static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) {
if (args.Length() != 2)
return v8::Undefined();
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 35d516e..f09b40a 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -15,8 +15,6 @@ var chrome = chrome || {};
native function GetNextRequestId();
native function OpenChannelToTab();
native function GetRenderViewId();
- native function GetPopupParentWindow();
- native function GetPopupView();
native function SetIconCommon();
native function IsExtensionProcess();
native function IsIncognitoProcess();
@@ -256,12 +254,6 @@ var chrome = chrome || {};
new chrome.Event("toolstrip.onCollapsed." + renderViewId);
}
- function setupPopupEvents(renderViewId) {
- chrome.experimental.popup = chrome.experimental.popup || {};
- chrome.experimental.popup.onClosed =
- new chrome.Event("experimental.popup.onClosed." + renderViewId);
- }
-
function setupHiddenContextMenuEvent(extensionId) {
chromeHidden.contextMenus = {};
chromeHidden.contextMenus.nextId = 1;
@@ -553,71 +545,6 @@ var chrome = chrome || {};
return tabIdProxy;
};
- apiFunctions["experimental.popup.show"].handleRequest =
- function(url, showDetails, callback) {
- // Second argument is a transform from HTMLElement to Rect.
- var internalSchema = [
- this.definition.parameters[0],
- {
- type: "object",
- name: "showDetails",
- properties: {
- domAnchor: {
- type: "object",
- properties: {
- top: { type: "integer", minimum: 0 },
- left: { type: "integer", minimum: 0 },
- width: { type: "integer", minimum: 0 },
- height: { type: "integer", minimum: 0 }
- }
- },
- giveFocus: {
- type: "boolean",
- optional: true
- },
- borderStyle: {
- type: "string",
- optional: true,
- enum: ["bubble", "rectangle"]
- },
- maxSize: {
- type: "object",
- optional: true,
- properties: {
- width: {
- type: "integer", optional: true, minimum: 32
- },
- height: {
- type: "integer", optional: true, minimum: 32
- }
- }
- }
- }
- },
- this.definition.parameters[2]
- ];
- return sendRequest(this.name,
- [url,
- {
- domAnchor: getAbsoluteRect(showDetails.relativeTo),
- giveFocus: showDetails.giveFocus,
- borderStyle: showDetails.borderStyle,
- maxSize: showDetails.maxSize
- },
- callback],
- internalSchema);
- };
-
- apiFunctions["experimental.extension.getPopupView"].handleRequest =
- function() {
- return GetPopupView();
- };
-
- apiFunctions["experimental.popup.getParentWindow"].handleRequest =
- function() {
- return GetPopupParentWindow();
- };
-
var canvas;
function setIconCommon(details, name, parameters, actionType, iconSize,
nativeFunction) {
@@ -794,7 +721,6 @@ var chrome = chrome || {};
setupPageActionEvents(extensionId);
setupToolstripEvents(GetRenderViewId());
- setupPopupEvents(GetRenderViewId());
setupHiddenContextMenuEvent(extensionId);
setupOmniboxEvents();
setupTtsEvents();
diff --git a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/background.html b/chrome/test/data/extensions/api_test/popup/popup_from_infobar/background.html
deleted file mode 100644
index 62b4e16..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/background.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<script>
-var pass = chrome.test.callbackPass;
-
-chrome.test.runTests([
- function testShowsAndCanGetParent() {
- chrome.tabs.getSelected(null, function(tab) {
- chrome.experimental.infobars.show(
- {tabId: tab.id, path:'in-infobar.html'});
- });
- // Flow continues in infobarCallback
- }
-]);
-
-function infobarCallback(showPopupFunc) {
- showPopupFunc();
- // Flow continues in popupCallback
-}
-
-function popupCallback(popupWindow, getFromParentFunc) {
- getFromParentFunc();
- var result = popupWindow.document.getElementById('target').innerText;
- if (!result) {
- chrome.test.fail('no result');
- }
- chrome.test.assertEq(result, '42');
- chrome.test.notifyPass();
-}
-
-</script>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-infobar.html b/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-infobar.html
deleted file mode 100644
index 8ea0fb8..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-infobar.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-<head>
-<script>
-window.magic = 42;
-
-function showPopup() {
- var anchor = document.getElementById('anchor');
- if (!anchor) {
- chrome.test.fail('no anchor');
- }
- chrome.experimental.popup.show(
- 'in-popup.html',
- {relativeTo: anchor});
-}
-
-function init() {
- chrome.extension.getBackgroundPage().infobarCallback(showPopup);
-}
-
-</script>
-</head>
-<body onload='init()'>
-<div id='anchor'>anchor</div>
-</body>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-popup.html b/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-popup.html
deleted file mode 100644
index b52ce9e..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/in-popup.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<html>
-<head>
-<script>
-
-function getFromParent() {
- var target = document.getElementById('target');
- if (!target) {
- chrome.test.fail('no target');
- }
- target.innerText = chrome.experimental.popup.getParentWindow().magic;
-}
-
-function init() {
- chrome.extension.getBackgroundPage().popupCallback(window, getFromParent);
-}
-
-</script>
-</head>
-<body onload="init()">
-<span id='target'></span>
-</body>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/manifest.json b/chrome/test/data/extensions/api_test/popup/popup_from_infobar/manifest.json
deleted file mode 100644
index d386cb6..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_from_infobar/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "Extension API test for chrome.experimental.popups from infobars.",
- "version": "1.0",
- "background_page": "background.html",
- "permissions": [
- "experimental", "tabs"
- ]
-}
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/background_page.html b/chrome/test/data/extensions/api_test/popup/popup_main/background_page.html
deleted file mode 100644
index aec295a..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/background_page.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script>
-window.onload = function() {
- // Create a tab in which the popup tests can execute.
- chrome.tabs.create({ "url": "dom_ui.html" });
-}
-</script>
-</head>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui.html
deleted file mode 100644
index 0d25161..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui.html
+++ /dev/null
@@ -1,307 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script>
-// A token assigned to the global context of this script so that subsequently
-// created tabs/views may find this view.
-var TESTING_TOKEN = true;
-
-// Constant storing the maximal size to which the popup may expand in the
-// following tests: popupRectangleMaxBoundsSizing, popupChromeMaxBoundsSizing
-var MAXIMAL_POPUP_SIZE = {
- "width": 320,
- "height": 240
-};
-
-var globalValue = "I am not 42.";
-
-// Some helper functions that track the focus state of a form on the toolbar.
-var formFocused = false;
-function onFormFocused() {
- formFocused = true;
-}
-
-function onFormBlurred() {
- formFocused = false;
-}
-
-// Global variable accessed by tests that run in popup views to indicate which
-// suite of tests to execute.
-var currentTest = null;
-
-// Callback that validates popup repositioning, and is invoked during execution
-// of the following tests:
-// popupRectangleSizing and popupChromeSizing.
-// |offset| specifies the delta in screen-space by which the browser was moved.
-// |initialSize| specfies the rect of the popup before the brower move.
-// |movedSize| specifies the rect of the popup after the browser move.
-function onWindowMoveCompleted(offset, initialSize, movedSize) {
- chrome.test.assertEq(initialSize.width, movedSize.width);
- chrome.test.assertEq(initialSize.height, movedSize.height);
- chrome.test.assertTrue(
- initialSize.top + offset.y == movedSize.top &&
- initialSize.left + offset.x == movedSize.left,
- "Popup repositioned incorrectly after browser move.");
-}
-
-// Callback invoked upon completion of popup bounds validation tests.
-// |newSize| is the size of the popup window after a resize operation.
-function onPopupWindowResizeCompleted(newSize) {
- // Note, we do not test for equality because the popup chrome may slightly
- // boost the size of the popup. For example, the rectangle chrome adds
- // a pixel to the dimensions of the popup.
- chrome.test.assertTrue(newSize.width - MAXIMAL_POPUP_SIZE.width <= 2);
- chrome.test.assertTrue(newSize.height - MAXIMAL_POPUP_SIZE.height <= 2);
-}
-
-// Assert function used by tests executed in separate extension views.
-// Used by the following test: popupTeardownDismissal
-// |value| is value upon which to assert.
-// |message| is displayed if |value| is false.
-function assertTrue(value, message) {
- chrome.test.assertTrue(value, message);
-}
-
-// Function used to signal completion of tests run in separate extension views.
-// Used by the following test: popupTeardownDismissal
-function testCompleted() {
- chrome.test.succeed();
-}
-
-window.onload = function() {
- chrome.test.runTests([
- function showNoFocusShift() {
- var entryForm = document.getElementById("entryForm").focus();
- chrome.test.assertTrue(formFocused);
-
- // Validate that displaying a pop-up with the giveFocus parameter assigned
- // to false does not touch the focus setting of the input field.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere"),
- "giveFocus": false
- };
-
- // The focus should also remain untouched during closing of the popup.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed, function() {
- chrome.test.assertTrue(formFocused);
- });
-
- chrome.experimental.popup.show("dom_ui_popup.html",
- showDetails,
- chrome.test.callbackPass(function() {
- chrome.test.assertTrue(formFocused);
- chrome.experimental.extension.getPopupView().close();
- }));
- },
- function noPopup() {
- chrome.test.assertTrue(
- undefined === chrome.experimental.extension.getPopupView(),
- "Popup view is defined when no popup shown.");
- chrome.test.succeed();
- },
- function noParentWindow() {
- chrome.test.assertTrue(
- undefined === chrome.experimental.popup.getParentWindow(),
- "Parent window accessible outside of popup view.");
- chrome.test.succeed();
- },
- function show() {
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere")
- };
- chrome.experimental.popup.show("dom_ui_popup.html",
- showDetails,
- chrome.test.callbackPass(function() {
- chrome.test.assertTrue(
- chrome.experimental.extension.getPopupView() != undefined);
- }));
- },
- function accessPopup() {
- var popupView = chrome.experimental.extension.getPopupView();
- chrome.test.assertTrue(popupView != undefined,
- "Unable to access popup view.");
-
- chrome.test.assertTrue(popupView.theAnswer != undefined,
- "Unable to access popup contents.");
-
- chrome.test.assertEq(42, popupView.theAnswer());
- chrome.test.succeed();
- },
- function accessHost() {
- var popupView = chrome.experimental.extension.getPopupView();
- chrome.test.assertTrue(popupView != undefined,
- "Unable to access popup view.");
-
- chrome.test.assertTrue(popupView.manipulateHost != undefined,
- "Unable to access popup contents.");
-
- popupView.manipulateHost();
- chrome.test.assertEq(42, globalValue);
- chrome.test.succeed();
- },
- function closePopup() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed, function() {
- // TODO(twiz): The following assert is disabled, because it makes
- // the test flaky on the build-bots. See issue: 46601
- // The popup should not be accessible during the onClosed handler.
- //chrome.test.assertTrue(
- // chrome.experimental.extension.getPopupView() == undefined);
- });
- chrome.experimental.extension.getPopupView().close();
- },
- function popupBlackBorder() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed);
-
- // Validate that displaying a pop-up with a black border still invokes
- // the callback successfully. Note that this test does not validate
- // the actual style of the border displayed.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere"),
- "borderStyle": "rectangle"
- };
- chrome.experimental.popup.show("dom_ui_popup.html",
- showDetails,
- chrome.test.callbackPass(function() {
- chrome.experimental.extension.getPopupView().close();
- }));
- },
- function disallowMultiplePopups() {
- // This test ensures that for a given extension with a popup displayed,
- // displaying a subsequent popup will dismiss the first.
- var showDetails1 = {
- "relativeTo": document.getElementById("anchorHere"),
- };
-
- var showDetails2 = {
- "relativeTo": document.getElementById("anchorHere2"),
- "borderStyle": "rectangle"
- };
-
- // Track the number of popups opened and closed, so that we can signal
- // the test as completed when appropriate.
- var numberClosed = 0;
- var doneListening = chrome.test.listenForever(
- chrome.experimental.popup.onClosed,
- function() {
- // This test expects to open and close two popups, so signify that
- // the test has succeeded, after closing the second popup.
- if (++numberClosed == 2) {
- doneListening();
- }
- });
-
- chrome.experimental.popup.show("dom_ui_popup_a.html",
- showDetails1,
- function() {
- // Validate that the popup view returned is the one we expect.
- chrome.test.assertEq(
- 'a',
- chrome.experimental.extension.getPopupView().getIdentity());
-
- // Ensure that only one popup is open.
- chrome.test.assertEq(
- 1,
- chrome.extension.getViews({type: "popup"}).length);
-
- chrome.experimental.popup.show("dom_ui_popup_b.html",
- showDetails2,
- function() {
- // Validate that the first popup view is fully closed, and that
- // getPopupView returns the most recently opened popup.
- chrome.test.assertEq(
- 'b',
- chrome.experimental.extension.getPopupView().getIdentity());
-
- // Ensure that only one popup is open.
- chrome.test.assertEq(
- 1,
- chrome.extension.getViews({type: 'popup'}).length);
-
- chrome.experimental.extension.getPopupView().close();
- });
- });
- },
- function popupChromeSizing() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed);
-
- // Ensure that popups with a chrome border are repositioned and sized
- // correctly.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere")
- };
-
- currentTest = "doSizingValidation";
- chrome.experimental.popup.show("dom_ui_popup_sizing.html",
- showDetails);
- },
- function popupRectangleSizing() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed);
-
- // Ensure that popups with a rectangle border are repositioned and sized
- // correctly.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere"),
- "borderStyle": "rectangle"
- };
-
- currentTest = "doSizingValidation";
- chrome.experimental.popup.show("dom_ui_popup_sizing.html",
- showDetails);
- },
- function popupChromeMaxBoundsSizing() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed);
-
- // Ensure that popups with a chrome border are repositioned and sized
- // correctly.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere"),
- "maxSize": MAXIMAL_POPUP_SIZE
- };
-
- currentTest = "doMaximalBoundsValidation";
- chrome.experimental.popup.show("dom_ui_popup_sizing.html",
- showDetails);
- },
- function popupRectangleMaxBoundsSizing() {
- // Ensure that the test waits until the popup is dismissed.
- chrome.test.listenOnce(chrome.experimental.popup.onClosed);
-
- // Ensure that popups with a rectangle border respects the maximal bounds.
- var showDetails = {
- "relativeTo": document.getElementById("anchorHere"),
- "borderStyle": "rectangle",
- "maxSize": MAXIMAL_POPUP_SIZE
- };
-
- currentTest = "doMaximalBoundsValidation";
- chrome.experimental.popup.show("dom_ui_popup_sizing.html",
- showDetails);
- },
- function popupTeardownDismissal() {
- // This test verifies that closing of views that launched active popups
- // results in a popup dismissal.
- var tabProperties = {
- "url": "dom_ui_popup_dismissal.html"
- };
- chrome.tabs.create(tabProperties);
- }
- ]);
-}
-</script>
-</head>
-<body>
-<div id="anchorHere">
-<span>TEST</span>
-</div>
-<div id="anchorHere2">
-<span>TESTING 2</span>
-</div>
-<form>
-<input id="entryForm" onfocus="onFormFocused();" onblur="onFormBlurred();"/>
-</form>
-</body>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup.html
deleted file mode 100644
index 67d4cdf..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
-<head>
-<script>
-function theAnswer() {
- return 42;
-}
-
-function manipulateHost() {
- var popupHost = chrome.experimental.popup.getParentWindow();
- if (popupHost && popupHost.globalValue) {
- popupHost.globalValue = 42;
- }
-}
-</script>
-</head>
-<body>
-Popup-Contents
-</body>
-</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_a.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_a.html
deleted file mode 100644
index 621fbec..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_a.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html>
-<head>
-<script>
-function getIdentity() {
- return 'a';
-}
-</script>
-</head>
-<body>
-Popup-A-Contents
-</body>
-</html>
-<html>
-<head>
-<script>
-function getIdentity() {
- return 'a';
-}
-</script>
-</head>
-<body>
-Popup-A-Contents
-</body>
-</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_b.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_b.html
deleted file mode 100644
index 5dd9792..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_b.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html>
-<head>
-<script>
-function getIdentity() {
- return 'b';
-}
-</script>
-</head>
-<body>
-Popup-B-Contents
-</body>
-</html>
-<html>
-<head>
-<script>
-function getIdentity() {
- return 'b';
-}
-</script>
-</head>
-<body>
-Popup-B-Contents
-</body>
-</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_dismissal.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_dismissal.html
deleted file mode 100644
index 5ba2839..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_dismissal.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script>
-var onbeforeunloadInvoked= false;
-var onunloadInvoked = false;
-var popupDismissed = false;
-var testingWindow = locateTestingWindow();
-
-// Helper function that locates the main tab that is being used
-// to drive the popup tests.
-function locateTestingWindow() {
- var extensionViews = chrome.extension.getViews();
- for (var i = 0; i < extensionViews.length; ++i) {
- // Look for the magic token defined on the testing page.
- if (typeof extensionViews[i].TESTING_TOKEN != "undefined" &&
- !!extensionViews[i].TESTING_TOKEN) {
- return extensionViews[i];
- }
- }
- return null;
-}
-
-// Onload handler that tests the popup dismissal behaviour when closing the
-// current tab. A popup is launched and the timing of the onClosed callback
-// is tested wrt the onbeforeunload and onunload callbacks.
-window.onload = function() {
- chrome.experimental.popup.onClosed.addListener(function() {
- testingWindow.assertTrue(onbeforeunloadInvoked,
- "Popup dismissed before onbeforeunload called.");
- testingWindow.assertTrue(!onunloadInvoked,
- "Popup dismissed after onunload called.");
- popupDismissed = true;
- });
-
- var showDetails = {
- "relativeTo": document.getElementById("popupAnchor")
- };
- chrome.experimental.popup.show("dom_ui_popup.html",
- showDetails,
- function() {
- chrome.tabs.getSelected(null, function(tab) {
- chrome.tabs.remove(tab.id);
- });
- });
-}
-
-window.onbeforeunload = function() {
- onbeforeunloadInvoked = true;
-}
-
-window.onunload = function() {
- onunloadInvoked = true;
-
- // If the popup was not yet dismissed, do not signal that the test has
- // completed. Let the test time-out to signal failure.
- if (popupDismissed)
- testingWindow.testCompleted();
-};
-</script>
-</head>
-<body>
-Testing Popup Sizing
-<div id='popupAnchor'>
-<span>Anchor Temporary Popup Here</span>
-</div>
-</body>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_sizing.html b/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_sizing.html
deleted file mode 100644
index 41d585f..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/dom_ui_popup_sizing.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script>
-// Returns the current size of the popup view.
-function getCurrentWindowSize() {
- return {
- "width": window.outerWidth,
- "height": window.outerHeight
- };
-}
-
-// Returns the current bounds of the displayed popup view.
-function getCurrentWindowBounds() {
- var windowSize = getCurrentWindowSize();
- return {
- "top": window.screenTop,
- "left": window.screenLeft,
- "width": windowSize.width,
- "height": windowSize.height
- };
-}
-
-// Utility that captures the size of the popup window before and after a browser
-// move and notifies the test's parent view of the respective sizes.
-function doSizingValidation() {
- var initialSize = getCurrentWindowBounds();
-
- // Move the browser, and ensure that the popup is repositioned correctly,
- // and retains its proper size.
- var offset = {'x': 5, 'y': 5};
- chrome.windows.getCurrent(function(browserWindow) {
- chrome.windows.update(browserWindow.id,
- {
- "left": browserWindow.left + offset.x,
- "top": browserWindow.top + offset.y
- },
- function(UpdatedWindow) {
- // Yield so that the window move notification may be processed before
- // invoking the callback. This is required because chrome.windows.update
- // calls its callback in a race with the windows message that repositions
- // the browser.
- // TODO: Fix this race condition so that the update callback is invoked
- // after all of the update machinery has been invoked.
- var updatePoller = setInterval(function() {
- var newPosition = getCurrentWindowBounds();
- if (newPosition.top != initialSize.top) {
- clearInterval(updatePoller);
- chrome.experimental.popup.getParentWindow().onWindowMoveCompleted(
- offset,
- initialSize,
- newPosition);
- window.close();
- }
- }, 50);
- });
- });
-}
-
-// Tests that resizing of the popup window, via a page-layout change, does not
-// result in a popup window that is larger than the specified maximal size.
-function doMaximalBoundsValidation() {
- var initialSize = getCurrentWindowSize();
-
- // Resize a portion of the page, and pass the resulting window size back
- // to the test host for validation.
- //var resizeDiv = document.getElementById("resizeMe");
- //resizeDiv.style.height = 1024;
- //resizeDiv.style.width = 1024;
- document.body.style.width = 1024;
- document.body.style.height = 1024;
-
- // Give the browser a chance to perform the resize.
- var updatePoller = setInterval(function() {
- var newSize = getCurrentWindowSize();
- if (newSize.width != initialSize.width) {
- clearInterval(updatePoller);
- chrome.experimental.popup.getParentWindow().
- onPopupWindowResizeCompleted(newSize);
- window.close();
- }
- }, 50);
-}
-
-// Invokes a test function based on the value of |test|.
-function runTest(test) {
- if ("doSizingValidation" == test)
- doSizingValidation();
-
- if ("doMaximalBoundsValidation" == test)
- doMaximalBoundsValidation();
-}
-
-window.onload = function() {
- // Delay invocation of the sizing test so that layout of the popup may
- // complete. On windows, onload is called before layout has been performed,
- // so window.screenTop, and the other fields used in getCurrentWindowSize will
- // return 0 until the layout has been performed.
- // TODO(twiz@chromium.org): Fix the order of the onload and layout processing.
- var positionPoller = setInterval(function() {
- var initialSize = getCurrentWindowSize();
- if (initialSize.width != 0) {
- clearInterval(positionPoller);
- runTest(chrome.experimental.popup.getParentWindow().currentTest);
- }
- }, 50);
-}
-</script>
-</head>
-<body style='width:128px; height:128px'>
-Testing Popup Sizing
-</body>
-</html>
diff --git a/chrome/test/data/extensions/api_test/popup/popup_main/manifest.json b/chrome/test/data/extensions/api_test/popup/popup_main/manifest.json
deleted file mode 100644
index 124430e..0000000
--- a/chrome/test/data/extensions/api_test/popup/popup_main/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "Extension API test for chrome.experimental.popup",
- "version": "1.0",
- "background_page": "background_page.html",
- "permissions": [
- "experimental", "tabs"
- ]
-}
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc
index 47a0e10..20baabe 100644
--- a/ui/views/focus/focus_manager.cc
+++ b/ui/views/focus/focus_manager.cc
@@ -86,7 +86,7 @@ void FocusManager::WidgetFocusManager::OnWidgetFocusEvent(
if (!enabled_)
return;
- // Perform a safe iteration over the focus listeners, as the array of
+ // Perform a safe iteration over the focus listeners, as the array
// may change during notification.
WidgetFocusChangeListenerList local_listeners(focus_change_listeners_);
WidgetFocusChangeListenerList::iterator iter(local_listeners.begin());
diff --git a/views/focus/focus_manager.cc b/views/focus/focus_manager.cc
index 5e5b2f4..13a03da 100644
--- a/views/focus/focus_manager.cc
+++ b/views/focus/focus_manager.cc
@@ -54,7 +54,7 @@ void FocusManager::WidgetFocusManager::OnWidgetFocusEvent(
if (!enabled_)
return;
- // Perform a safe iteration over the focus listeners, as the array of
+ // Perform a safe iteration over the focus listeners, as the array
// may change during notification.
WidgetFocusChangeListenerList local_listeners(focus_change_listeners_);
WidgetFocusChangeListenerList::iterator iter(local_listeners.begin());