diff options
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tabs_module.cc | 38 | ||||
-rw-r--r-- | chrome/browser/ui/browser.cc | 31 | ||||
-rw-r--r-- | chrome/browser/ui/browser.h | 8 | ||||
-rw-r--r-- | chrome/browser/ui/views/aura/panel_view_aura.cc | 263 | ||||
-rw-r--r-- | chrome/browser/ui/views/aura/panel_view_aura.h | 77 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/chrome_view_type.cc | 1 | ||||
-rw-r--r-- | chrome/common/chrome_view_type.h | 2 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_custom_bindings.cc | 2 |
11 files changed, 428 insertions, 7 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 3daf716..29c397f 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -2987,6 +2987,9 @@ void TestingAutomationProvider::GetBrowserInfo( case chrome::VIEW_TYPE_APP_SHELL: type = "APP_SHELL"; break; + case chrome::VIEW_TYPE_PANEL: + type = "PANEL"; + break; default: type = "unknown"; break; diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 1df61e6..1f0bc4f 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -332,7 +332,8 @@ void ExtensionHost::DidStopLoading() { if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || - extension_host_type_ == chrome::VIEW_TYPE_APP_SHELL) { + extension_host_type_ == chrome::VIEW_TYPE_APP_SHELL || + extension_host_type_ == chrome::VIEW_TYPE_PANEL) { #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) if (view_.get()) view_->DidStopLoading(); @@ -353,6 +354,8 @@ void ExtensionHost::DidStopLoading() { since_created_.Elapsed()); } else if (extension_host_type_ == chrome::VIEW_TYPE_APP_SHELL) { UMA_HISTOGRAM_TIMES("Extensions.ShellLoadTime", since_created_.Elapsed()); + } else if (extension_host_type_ == chrome::VIEW_TYPE_PANEL) { + UMA_HISTOGRAM_TIMES("Extensions.PanelLoadTime", since_created_.Elapsed()); } // Send the notification last, because it might result in this being @@ -396,7 +399,8 @@ void ExtensionHost::CloseContents(WebContents* contents) { extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || - extension_host_type_ == chrome::VIEW_TYPE_APP_SHELL) { + extension_host_type_ == chrome::VIEW_TYPE_APP_SHELL || + extension_host_type_ == chrome::VIEW_TYPE_PANEL) { content::NotificationService::current()->Notify( chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, content::Source<Profile>(profile_), diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 89f59c8..7ce8624 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -61,6 +61,12 @@ #include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/codec/png_codec.h" +#if defined(USE_AURA) +#include "ash/ash_switches.h" +#include "base/command_line.h" +#include "chrome/browser/ui/views/aura/panel_view_aura.h" +#endif + namespace keys = extension_tabs_module_constants; namespace errors = extension_manifest_errors; @@ -507,7 +513,13 @@ bool CreateWindowFunction::RunImpl() { extension_id = GetExtension()->id(); } else if (type_str == keys::kWindowTypeValuePanel) { extension_id = GetExtension()->id(); - if (PanelManager::ShouldUsePanels(extension_id)) + bool use_panels = PanelManager::ShouldUsePanels(extension_id); +#if defined(USE_AURA) + if (CommandLine::ForCurrentProcess()->HasSwitch( + ash::switches::kAuraPanelManager)) + use_panels = true; +#endif + if (use_panels) window_type = Browser::TYPE_PANEL; else window_type = Browser::TYPE_POPUP; @@ -518,10 +530,24 @@ bool CreateWindowFunction::RunImpl() { } } - // Unlike other window types, Panels do not take focus by default. - if (!saw_focus_key && window_type == Browser::TYPE_PANEL) - focused = false; +#if defined(USE_AURA) + // Aura Panels create a new PanelDOMView. + if (CommandLine::ForCurrentProcess()->HasSwitch( + ash::switches::kAuraPanelManager) && + window_type == Browser::TYPE_PANEL) { + // Note: Panels ignore all but the first url provided. + std::string title = + web_app::GenerateApplicationNameFromExtensionId(extension_id); + PanelViewAura* panel_view = new PanelViewAura(title); + panel_view->Init(window_profile, urls[0], panel_bounds); + // TODO(stevenjb): Provide an interface enable handles for any view, not + // just browsers. See crbug.com/113412. + result_.reset(Value::CreateNullValue()); + return true; + } +#endif + // Create a new BrowserWindow. Browser* new_window; if (extension_id.empty()) { new_window = Browser::CreateForType(window_type, window_profile); @@ -544,6 +570,10 @@ bool CreateWindowFunction::RunImpl() { } new_window->SelectNumberedTab(0); + // Unlike other window types, Panels do not take focus by default. + if (!saw_focus_key && window_type == Browser::TYPE_PANEL) + focused = false; + if (focused) new_window->window()->Show(); else diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 7afd5e5..e5b7a3a 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -207,7 +207,9 @@ #endif #if defined(USE_AURA) +#include "ash/ash_switches.h" #include "ash/shell.h" +#include "chrome/browser/ui/views/aura/panel_view_aura.h" #endif #if !defined(OS_CHROMEOS) || defined(USE_AURA) @@ -698,8 +700,17 @@ WebContents* Browser::OpenApplication( tab = shell_window->web_contents(); break; } - case extension_misc::LAUNCH_WINDOW: case extension_misc::LAUNCH_PANEL: +#if defined(USE_AURA) + if (extension && + CommandLine::ForCurrentProcess()->HasSwitch( + ash::switches::kAuraPanelManager)) { + tab = OpenApplicationPanel(profile, extension, override_url); + break; + } + // else fall through to LAUNCH_WINDOW +#endif + case extension_misc::LAUNCH_WINDOW: tab = Browser::OpenApplicationWindow(profile, extension, container, override_url, NULL); break; @@ -715,6 +726,24 @@ WebContents* Browser::OpenApplication( return tab; } +#if defined(USE_AURA) +// static +WebContents* Browser::OpenApplicationPanel( + Profile* profile, + const Extension* extension, + const GURL& url_input) { + GURL url = UrlForExtension(extension, url_input); + std::string app_name = + web_app::GenerateApplicationNameFromExtensionId(extension->id()); + gfx::Rect panel_bounds; + panel_bounds.set_width(extension->launch_width()); + panel_bounds.set_height(extension->launch_height()); + PanelViewAura* panel_view = new PanelViewAura(app_name); + panel_view->Init(profile, url, panel_bounds); + return panel_view->WebContents(); +} +#endif + // static WebContents* Browser::OpenApplicationWindow( Profile* profile, diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index d4a975c..96bd1ee 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -277,6 +277,14 @@ class Browser : public TabHandlerDelegate, const GURL& override_url, WindowOpenDisposition disposition); +#if defined(USE_AURA) + // Opens |url| in a new application panel window for the specified url. + static content::WebContents* OpenApplicationPanel( + Profile* profile, + const Extension* extension, + const GURL& url); +#endif + // Opens a new application window for the specified url. If |as_panel| // is true, the application will be opened as a Browser::Type::APP_PANEL in // app panel window, otherwise it will be opened as as either diff --git a/chrome/browser/ui/views/aura/panel_view_aura.cc b/chrome/browser/ui/views/aura/panel_view_aura.cc new file mode 100644 index 0000000..9b058dd --- /dev/null +++ b/chrome/browser/ui/views/aura/panel_view_aura.cc @@ -0,0 +1,263 @@ +// Copyright (c) 2012 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/ui/views/aura/panel_view_aura.h" + +#include "ash/wm/panel_frame_view.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/common/chrome_view_type.h" +#include "chrome/common/extensions/extension_messages.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "googleurl/src/gurl.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ui/aura/window.h" +#include "ui/views/widget/widget.h" + +namespace { +const int kMinWidth = 100; +const int kMinHeight = 100; +const int kDefaultWidth = 200; +const int kDefaultHeight = 300; +} + +//////////////////////////////////////////////////////////////////////////////// +// PanelHost + +namespace internal { + +class PanelHost : public content::WebContentsDelegate, + public content::WebContentsObserver, + public ExtensionFunctionDispatcher::Delegate { + public: + explicit PanelHost(PanelViewAura* panel_view, Profile* profile); + virtual ~PanelHost(); + + void Init(const GURL& url); + + content::WebContents* web_contents() const { return web_contents_.get(); } + + // ExtensionFunctionDispatcher::Delegate overrides. + virtual Browser* GetBrowser() OVERRIDE; + virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE; + + // content::WebContentsDelegate implementation: + virtual void CloseContents(content::WebContents* source) OVERRIDE; + virtual void HandleMouseDown() OVERRIDE; + virtual void UpdatePreferredSize(content::WebContents* source, + const gfx::Size& pref_size) OVERRIDE; + virtual void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) OVERRIDE; + + // content::WebContentsObserver implementation: + virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; + virtual void RenderViewReady() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + protected: + // Message handlers + void OnRequest(const ExtensionHostMsg_Request_Params& params); + + private: + PanelViewAura* panel_view_; + Profile* profile_; + ExtensionFunctionDispatcher extension_function_dispatcher_; + scoped_ptr<content::WebContents> web_contents_; + // Site instance to be used for opening new links. + scoped_refptr<content::SiteInstance> site_instance_; +}; + +PanelHost::PanelHost(PanelViewAura* panel_view, Profile* profile) + : panel_view_(panel_view), + profile_(profile), + ALLOW_THIS_IN_INITIALIZER_LIST( + extension_function_dispatcher_(profile, this)) { +} + +PanelHost::~PanelHost() { +} + +void PanelHost::Init(const GURL& url) { + site_instance_ = content::SiteInstance::CreateForURL(profile_, url); + + web_contents_.reset(content::WebContents::Create( + profile_, site_instance_.get(), MSG_ROUTING_NONE, NULL, NULL)); + web_contents_->SetViewType(chrome::VIEW_TYPE_PANEL); + web_contents_->SetDelegate(this); + Observe(web_contents_.get()); + + web_contents_->GetController().LoadURL( + url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); +} + +Browser* PanelHost::GetBrowser() { + return NULL; +} + +content::WebContents* PanelHost::GetAssociatedWebContents() const { + return web_contents_.get(); +} + +void PanelHost::CloseContents(content::WebContents* source) { + panel_view_->CloseView(); +} + +void PanelHost::HandleMouseDown() { +} + +void PanelHost::UpdatePreferredSize(content::WebContents* source, + const gfx::Size& pref_size) { + panel_view_->SetContentPreferredSize(pref_size); +} + +// This handles launching a new page from within the panel. +// TODO(stevenjb): Determine whether or not this is the desired/expected +// behavior for panels. +void PanelHost::AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + Browser* browser = BrowserList::GetLastActiveWithProfile( + Profile::FromBrowserContext(new_contents->GetBrowserContext())); + if (!browser) + return; + browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture); +} + +void PanelHost::RenderViewCreated(RenderViewHost* render_view_host) { +} + +void PanelHost::RenderViewReady() { +} + +void PanelHost::RenderViewGone(base::TerminationStatus status) { + CloseContents(web_contents_.get()); +} + +bool PanelHost::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PanelHost, message) + IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PanelHost::OnRequest(const ExtensionHostMsg_Request_Params& params) { + extension_function_dispatcher_.Dispatch(params, + web_contents_->GetRenderViewHost()); +} + +} // namespace internal + +//////////////////////////////////////////////////////////////////////////////// +// PanelViewAura + +PanelViewAura::PanelViewAura(const std::string& title) + : title_(title), + preferred_size_(kMinWidth, kMinHeight), + widget_(NULL) { +} + +PanelViewAura::~PanelViewAura() { +} + +views::Widget* PanelViewAura::Init(Profile* profile, + const GURL& url, + const gfx::Rect& bounds) { + widget_ = new views::Widget; + views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL); + params.delegate = this; + + params.bounds = bounds; + if (params.bounds.width() == 0) + params.bounds.set_width(kDefaultWidth); + else if (params.bounds.width() < kMinWidth) + params.bounds.set_width(kMinWidth); + + if (params.bounds.height() == 0) + params.bounds.set_height(kDefaultHeight); + else if (params.bounds.height() < kMinHeight) + params.bounds.set_height(kMinHeight); + + widget_->Init(params); + widget_->GetNativeView()->SetName(title_); + + host_.reset(new internal::PanelHost(this, profile)); + host_->Init(url); + + Attach(host_->web_contents()->GetNativeView()); + + widget_->Show(); + + return widget_; +} + +content::WebContents* PanelViewAura::WebContents() { + return host_->web_contents(); +} + +void PanelViewAura::CloseView() { + widget_->CloseNow(); +} + +void PanelViewAura::SetContentPreferredSize(const gfx::Size& size) { + if (size.width() > kMinWidth) + preferred_size_.set_width(size.width()); + if (size.height() > kMinHeight) + preferred_size_.set_height(size.height()); +} + +// views::View implementation: + +gfx::Size PanelViewAura::GetPreferredSize() { + return preferred_size_; +} + +// views::WidgetDelegate implementation: + +bool PanelViewAura::CanResize() const { + // TODO(stevenjb): Can/should panels be able to prevent resizing? + return true; +} + +string16 PanelViewAura::GetWindowTitle() const { + return UTF8ToUTF16(title_); +} + +views::View* PanelViewAura::GetContentsView() { + return this; +} + +views::View* PanelViewAura::GetInitiallyFocusedView() { + return this; +} + +bool PanelViewAura::ShouldShowWindowTitle() const { + return true; +} + +views::Widget* PanelViewAura::GetWidget() { + return View::GetWidget(); +} + +const views::Widget* PanelViewAura::GetWidget() const { + return View::GetWidget(); +} + +views::NonClientFrameView* PanelViewAura::CreateNonClientFrameView() { + return new ash::PanelFrameView(); +} diff --git a/chrome/browser/ui/views/aura/panel_view_aura.h b/chrome/browser/ui/views/aura/panel_view_aura.h new file mode 100644 index 0000000..66d2191 --- /dev/null +++ b/chrome/browser/ui/views/aura/panel_view_aura.h @@ -0,0 +1,77 @@ +// Copyright (c) 2012 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_UI_VIEWS_AURA_PANEL_VIEW_AURA_H_ +#define CHROME_BROWSER_UI_VIEWS_AURA_PANEL_VIEW_AURA_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "ui/gfx/size.h" +#include "ui/views/controls/native/native_view_host.h" +#include "ui/views/widget/widget_delegate.h" + +class GURL; +class Profile; + +namespace content { +class WebContents; +} + +namespace views { +class Widget; +} + +namespace internal { +class PanelHost; +} + +/////////////////////////////////////////////////////////////////////////////// +// PanelViewAura is used to display HTML in a Panel window. +// +class PanelViewAura : public views::NativeViewHost, + public views::WidgetDelegate { + public: + explicit PanelViewAura(const std::string& title); + virtual ~PanelViewAura(); + + views::Widget* Init(Profile* profile, + const GURL& url, + const gfx::Rect& bounds); + + // Returns the WebContents associated with this panel. + content::WebContents* WebContents(); + + // Close the panel window. + void CloseView(); + + // Set the preferred size of the contents. + void SetContentPreferredSize(const gfx::Size& size); + + // Overridden from views::View: + virtual gfx::Size GetPreferredSize() OVERRIDE; + + // Overridden from views::WidgetDelegate: + virtual bool CanResize() const OVERRIDE; + virtual string16 GetWindowTitle() const OVERRIDE; + virtual views::View* GetContentsView() OVERRIDE; + virtual views::View* GetInitiallyFocusedView() OVERRIDE; + virtual bool ShouldShowWindowTitle() const OVERRIDE; + virtual views::Widget* GetWidget() OVERRIDE; + virtual const views::Widget* GetWidget() const OVERRIDE; + virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE; + + private: + std::string title_; + gfx::Size preferred_size_; + // Owned internal host class implementing WebContents and Extension Delegates. + scoped_ptr<internal::PanelHost> host_; + // Unowned pointer to the widget. + views::Widget* widget_; + + DISALLOW_COPY_AND_ASSIGN(PanelViewAura); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_AURA_PANEL_VIEW_AURA_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 432b6a8..4e1bbc9 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3450,6 +3450,8 @@ 'browser/ui/views/aura/caps_lock_handler.h', 'browser/ui/views/aura/chrome_shell_delegate.cc', 'browser/ui/views/aura/chrome_shell_delegate.h', + 'browser/ui/views/aura/panel_view_aura.cc', + 'browser/ui/views/aura/panel_view_aura.h', 'browser/ui/views/aura/launcher_app_icon_loader.cc', 'browser/ui/views/aura/launcher_app_icon_loader.h', 'browser/ui/views/aura/launcher_icon_updater.cc', diff --git a/chrome/common/chrome_view_type.cc b/chrome/common/chrome_view_type.cc index b41c1a1..7b15a26 100644 --- a/chrome/common/chrome_view_type.cc +++ b/chrome/common/chrome_view_type.cc @@ -8,6 +8,7 @@ namespace chrome { const char kViewTypeTabContents[] = "TAB"; const char kViewTypeBackgroundPage[] = "BACKGROUND"; const char kViewTypePopup[] = "POPUP"; +const char kViewTypePanel[] = "PANEL"; const char kViewTypeInfobar[] = "INFOBAR"; const char kViewTypeNotification[] = "NOTIFICATION"; const char kViewTypeExtensionDialog[] = "EXTENSION_DIALOG"; diff --git a/chrome/common/chrome_view_type.h b/chrome/common/chrome_view_type.h index d716fe1..1dc2044 100644 --- a/chrome/common/chrome_view_type.h +++ b/chrome/common/chrome_view_type.h @@ -21,6 +21,7 @@ enum ViewType { VIEW_TYPE_NOTIFICATION, VIEW_TYPE_EXTENSION_DIALOG, VIEW_TYPE_APP_SHELL, + VIEW_TYPE_PANEL, }; // Constant strings corresponding to the Type enumeration values. Used @@ -28,6 +29,7 @@ enum ViewType { extern const char kViewTypeTabContents[]; extern const char kViewTypeBackgroundPage[]; extern const char kViewTypePopup[]; +extern const char kViewTypePanel[]; extern const char kViewTypeInfobar[]; extern const char kViewTypeNotification[]; extern const char kViewTypeExtensionDialog[]; diff --git a/chrome/renderer/extensions/extension_custom_bindings.cc b/chrome/renderer/extensions/extension_custom_bindings.cc index 363f02a..449c031 100644 --- a/chrome/renderer/extensions/extension_custom_bindings.cc +++ b/chrome/renderer/extensions/extension_custom_bindings.cc @@ -152,6 +152,8 @@ v8::Handle<v8::Value> ExtensionCustomBindings::GetExtensionViews( view_type = chrome::VIEW_TYPE_EXTENSION_DIALOG; } else if (view_type_string == chrome::kViewTypeAppShell) { view_type = chrome::VIEW_TYPE_APP_SHELL; + } else if (view_type_string == chrome::kViewTypePanel) { + view_type = chrome::VIEW_TYPE_PANEL; } else if (view_type_string != chrome::kViewTypeAll) { return v8::Undefined(); } |