diff options
28 files changed, 266 insertions, 22 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index ac6701a..8bdbc81 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -369,7 +369,7 @@ gfx::Rect Browser::GetSavedWindowBounds() const { gfx::Rect restored_bounds = override_bounds_; bool maximized; - WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, + WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, NULL, &restored_bounds, &maximized); return restored_bounds; } @@ -388,7 +388,7 @@ bool Browser::GetSavedMaximizedState() const { // An explicit maximized state was not set. Query the window sizer. gfx::Rect restored_bounds; bool maximized = false; - WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, + WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, NULL, &restored_bounds, &maximized); return maximized; } @@ -1980,6 +1980,12 @@ void Browser::RenderWidgetShowing() { window_->DisableInactiveFrame(); } +ExtensionFunctionDispatcher* Browser::CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id) { + return new ExtensionFunctionDispatcher(render_view_host, this, extension_id); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, SelectFileDialog::Listener implementation: diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index a6c5322..b59d4ff 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -486,6 +486,9 @@ class Browser : public TabStripModelDelegate, void* parent_window); virtual void SetFocusToLocationBar(); virtual void RenderWidgetShowing(); + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id); // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const FilePath& path, int index, void* params); diff --git a/chrome/browser/browser_list.cc b/chrome/browser/browser_list.cc index 411583b..ca2963f 100644 --- a/chrome/browser/browser_list.cc +++ b/chrome/browser/browser_list.cc @@ -194,6 +194,18 @@ Browser* BrowserList::GetLastActive() { } // static +Browser* BrowserList::GetLastActiveWithProfile(Profile* p) { + list_type::reverse_iterator browser = last_active_browsers_.rbegin(); + for (; browser != last_active_browsers_.rend(); ++browser) { + if ((*browser)->profile() == p) { + return *browser; + } + } + + return NULL; +} + +// static Browser* BrowserList::FindBrowserWithType(Profile* p, Browser::Type t) { Browser* last_active = GetLastActive(); if (last_active && last_active->profile() == p && last_active->type() == t) diff --git a/chrome/browser/browser_list.h b/chrome/browser/browser_list.h index 858e97e..2488a09 100644 --- a/chrome/browser/browser_list.h +++ b/chrome/browser/browser_list.h @@ -50,6 +50,10 @@ class BrowserList { // in the list. If no Browsers exist, returns NULL. static Browser* GetLastActive(); + // Identical in behavior to GetLastActive(), except that the most recently + // open browser owned by |profile| is returned. If none exist, returns NULL. + static Browser* GetLastActiveWithProfile(Profile *profile); + // Find an existing browser window with the provided type. If the last active // has the right type, it is returned. Otherwise, the next available browser // is returned. Returns NULL if no such browser currently exists. diff --git a/chrome/browser/extensions/extension_function.h b/chrome/browser/extensions/extension_function.h index cc1d049..2c460eb 100644 --- a/chrome/browser/extensions/extension_function.h +++ b/chrome/browser/extensions/extension_function.h @@ -71,8 +71,11 @@ class ExtensionFunction { // returning. The calling renderer process will be killed. bool bad_message_; - private: + // The dispatcher that will service this extension function call. ExtensionFunctionDispatcher* dispatcher_; + + private: + // Id of js function to callback upon completion. -1 represents no callback. int callback_id_; DISALLOW_COPY_AND_ASSIGN(ExtensionFunction); diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 6545f6f..5ca347b 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -52,6 +52,7 @@ FactoryRegistry::FactoryRegistry() { // Tabs factories_["GetWindows"] = &NewExtensionFunction<GetWindowsFunction>; + factories_["CreateWindow"] = &NewExtensionFunction<CreateWindowFunction>; factories_["GetTabsForWindow"] = &NewExtensionFunction<GetTabsForWindowFunction>; factories_["GetTab"] = &NewExtensionFunction<GetTabFunction>; @@ -97,8 +98,10 @@ void ExtensionFunctionDispatcher::GetAllFunctionNames( ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( RenderViewHost* render_view_host, + Browser* browser, const std::string& extension_id) : render_view_host_(render_view_host), + browser_(browser), extension_id_(extension_id) { } diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h index ab3a07d..1ffb3d4 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.h +++ b/chrome/browser/extensions/extension_function_dispatcher.h @@ -10,9 +10,11 @@ #include "base/values.h" +class Browser; class ExtensionFunction; class Profile; class RenderViewHost; +class RenderViewHostDelegate; // ExtensionFunctionDispatcher receives requests to execute functions from // Chromium extensions running in a RenderViewHost and dispatches them to the @@ -23,6 +25,7 @@ class ExtensionFunctionDispatcher { static void GetAllFunctionNames(std::vector<std::string>* names); ExtensionFunctionDispatcher(RenderViewHost* render_view_host, + Browser* browser, const std::string& extension_id); // Handle a request to execute an extension function. @@ -32,6 +35,8 @@ class ExtensionFunctionDispatcher { // Send a response to a function. void SendResponse(ExtensionFunction* api); + Browser* browser() { return browser_; } + // Handle a malformed message. Possibly the result of an attack, so kill // the renderer. void HandleBadMessage(ExtensionFunction* api); @@ -45,6 +50,8 @@ class ExtensionFunctionDispatcher { private: RenderViewHost* render_view_host_; + Browser* browser_; + std::string extension_id_; }; diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 278ebd7..67f4cc6 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -8,8 +8,16 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/tab_contents/navigation_entry.h" +// TODO(port): Port these files. +#if defined(OS_WIN) +#include "chrome/browser/window_sizer.h" +#else +#include "chrome/common/temp_scaffolding_stubs.h" +#endif + // Forward declare static helper functions defined below. static DictionaryValue* CreateWindowValue(Browser* browser); static ListValue* CreateTabList(Browser* browser); @@ -72,6 +80,72 @@ bool GetWindowsFunction::RunImpl() { return true; } +bool CreateWindowFunction::RunImpl() { + scoped_ptr<GURL> url(new GURL()); + + // Look for optional url. + if (args_->IsType(Value::TYPE_DICTIONARY)) { + const DictionaryValue *args = static_cast<const DictionaryValue*>(args_); + std::string url_input; + if (args->GetString(L"url", &url_input)) { + url.reset(new GURL(url_input)); + if (!url->is_valid()) { + // TODO(rafaelw): need error message/callback here + return false; + } + } + } + + // Try to get the browser associated with view that this call came from, so + // its position can be set relative to its browser window. + Browser* browser = dispatcher_->browser(); + if (browser == NULL) + browser = BrowserList::GetLastActiveWithProfile(dispatcher_->profile()); + + // Try to position the new browser relative its originating browser window. + gfx::Rect empty_bounds; + gfx::Rect bounds; + bool maximized; + // The call offsets the bounds by kWindowTilePixels (defined in WindowSizer to + // be 10). + WindowSizer::GetBrowserWindowBounds(std::wstring(), empty_bounds, browser, + &bounds, &maximized); + + // Any part of the bounds can optionally be set by the caller. + if (args_->IsType(Value::TYPE_DICTIONARY)) { + const DictionaryValue *args = static_cast<const DictionaryValue*>(args_); + int bounds_val; + if (args->GetInteger(L"left", &bounds_val)) + bounds.set_x(bounds_val); + + if (args->GetInteger(L"top", &bounds_val)) + bounds.set_y(bounds_val); + + if (args->GetInteger(L"width", &bounds_val)) + bounds.set_width(bounds_val); + + if (args->GetInteger(L"height", &bounds_val)) + bounds.set_height(bounds_val); + } + + Browser *new_window = Browser::Create(dispatcher_->profile()); + if (url->is_valid()) { + new_window->AddTabWithURL(*(url.get()), + GURL(), PageTransition::LINK, + true, -1, NULL); + } else { + new_window->NewTab(); + } + new_window->window()->SetBounds(bounds); + new_window->window()->Show(); + + // TODO(rafaelw): support |focused|, |zIndex| + + result_.reset(CreateWindowValue(new_window)); + + return true; +} + bool GetTabsForWindowFunction::RunImpl() { if (!args_->IsType(Value::TYPE_NULL)) return false; @@ -123,7 +197,7 @@ bool CreateTabFunction::RunImpl() { } TabContents* contents = browser->AddTabWithURL(GURL(url), GURL(), - PageTransition::TYPED, selected, index, NULL); + PageTransition::LINK, selected, index, NULL); index = tab_strip->GetIndexOfTabContents(contents); // Return data about the newly created tab. @@ -186,7 +260,7 @@ bool UpdateTabFunction::RunImpl() { if (args->GetString(L"url", &url)) { GURL new_gurl(url); if (new_gurl.is_valid()) { - controller.LoadURL(new_gurl, GURL(), PageTransition::TYPED); + controller.LoadURL(new_gurl, GURL(), PageTransition::LINK); } else { // TODO(rafaelw): return some reasonable error? } diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h index 5abfab8..617fcf9 100644 --- a/chrome/browser/extensions/extension_tabs_module.h +++ b/chrome/browser/extensions/extension_tabs_module.h @@ -20,6 +20,9 @@ class ExtensionTabUtil { class GetWindowsFunction : public SyncExtensionFunction { virtual bool RunImpl(); }; +class CreateWindowFunction : public SyncExtensionFunction { + virtual bool RunImpl(); +}; class GetTabsForWindowFunction : public SyncExtensionFunction { virtual bool RunImpl(); }; diff --git a/chrome/browser/extensions/extension_view.cc b/chrome/browser/extensions/extension_view.cc index a26194c..2332886 100755 --- a/chrome/browser/extensions/extension_view.cc +++ b/chrome/browser/extensions/extension_view.cc @@ -39,6 +39,13 @@ ExtensionView::ExtensionView(Extension* extension, pending_preferred_width_(0) { } +ExtensionFunctionDispatcher* ExtensionView:: + CreateExtensionFunctionDispatcher(RenderViewHost *render_view_host, + const std::string& extension_id) { + return new ExtensionFunctionDispatcher(render_view_host, browser_, + extension_id); +} + void ExtensionView::ShowIfCompletelyLoaded() { // We wait to show the ExtensionView until it has loaded and our parent has // given us a background. These can happen in different orders. diff --git a/chrome/browser/extensions/extension_view.h b/chrome/browser/extensions/extension_view.h index 51c84a3..429f89f 100755 --- a/chrome/browser/extensions/extension_view.h +++ b/chrome/browser/extensions/extension_view.h @@ -18,6 +18,7 @@ class Browser; class Extension; +class ExtensionFunctionDispatcher; class RenderWidgetHost; class RenderWidgetHostView; class WebContents; @@ -47,6 +48,9 @@ class ExtensionView : public HWNDHtmlView, // RenderViewHostDelegate // TODO(mpcomplete): GetProfile is unused. virtual Profile* GetProfile() const { return NULL; } + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost *render_view_host, + const std::string& extension_id); virtual void RenderViewCreated(RenderViewHost* render_view_host); virtual void DidContentsPreferredWidthChange(const int pref_width); virtual void DidStopLoading(RenderViewHost* render_view_host, diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc index e493421..e1c3d8d 100755 --- a/chrome/browser/extensions/extension_view_unittest.cc +++ b/chrome/browser/extensions/extension_view_unittest.cc @@ -39,6 +39,12 @@ class MockExtensionView : public ExtensionView { ui_test_utils::RunMessageLoop(); } + virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host) { + NOTREACHED(); + return NULL; + } + bool got_message() { return got_message_; } private: virtual void RunJavaScriptMessage( diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc index a66e2c2..8bcdead 100644 --- a/chrome/browser/external_tab_container.cc +++ b/chrome/browser/external_tab_container.cc @@ -8,6 +8,7 @@ #include "base/win_util.h" #include "chrome/browser/automation/automation_provider.h" #include "chrome/browser/browser.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/load_notification_details.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/provisional_load_details.h" @@ -162,7 +163,7 @@ void ExternalTabContainer::OpenURLFromTab(TabContents* source, break; default: break; - } + } } void ExternalTabContainer::NavigationStateChanged(const TabContents* source, @@ -398,6 +399,12 @@ bool ExternalTabContainer::IsExternalTabContainer(HWND window) { return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0; } +ExtensionFunctionDispatcher* ExternalTabContainer:: + CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host, + const std::string& extension_id) { + return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id); +} + // static ExternalTabContainer* ExternalTabContainer::GetContainerForTab( HWND tab_window) { diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h index 4f7750b..2d0b9bd 100644 --- a/chrome/browser/external_tab_container.h +++ b/chrome/browser/external_tab_container.h @@ -88,6 +88,11 @@ class ExternalTabContainer : public TabContentsDelegate, return true; }; + // Creates an ExtensionFunctionDispatcher that has no browser + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id); + virtual bool TakeFocus(bool reverse); // Notification service callback. diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 21b8d34..bd4f092 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -890,8 +890,8 @@ void RenderViewHost::OnMsgNavigate(const IPC::Message& msg) { if (PageTransition::IsMainFrame(validated_params.transition)) { ExtensionFunctionDispatcher* new_efd = NULL; if (validated_params.url.SchemeIs(chrome::kExtensionScheme)) { - new_efd = new ExtensionFunctionDispatcher(this, - validated_params.url.host()); + new_efd = delegate()->CreateExtensionFunctionDispatcher(this, + validated_params.url.host()); } extension_function_dispatcher_.reset(new_efd); } @@ -1352,6 +1352,7 @@ void RenderViewHost::OnExtensionRequest(const std::string& name, int callback_id) { // TODO(aa): Here is where we can check that this renderer was supposed to be // able to call extension APIs. + DCHECK(extension_function_dispatcher_.get()); extension_function_dispatcher_->HandleRequest(name, args, callback_id); } diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index ba69b03..18b1f38 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -19,7 +19,10 @@ #include "webkit/glue/webpreferences.h" #include "webkit/glue/window_open_disposition.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" + class AutofillForm; +class ExtensionFunctionDispatcher; class NavigationEntry; class Profile; class RenderProcessHost; @@ -147,6 +150,14 @@ class RenderViewHostDelegate { // Retrieves the profile to be used. virtual Profile* GetProfile() const = 0; + // Create a new browser window to be sized, shown and contents managed + // by the caller. + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id) { + return NULL; + } + // Return this object cast to a WebContents, if it is one. virtual WebContents* GetAsWebContents() { return NULL; } diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index fe4ed7a..f11a3c9 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1598,6 +1598,13 @@ WebContents* TabContents::GetAsWebContents() { return AsWC(this); } +ExtensionFunctionDispatcher* TabContents::CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id) { + return delegate()->CreateExtensionFunctionDispatcher(render_view_host, + extension_id); +} + void TabContents::RenderViewCreated(RenderViewHost* render_view_host) { NavigationEntry* entry = controller_.GetActiveEntry(); if (!entry) diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 4709cab..8630e42 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -726,6 +726,9 @@ class TabContents : public PageNavigator, virtual RenderViewHostDelegate::View* GetViewDelegate() const; virtual RenderViewHostDelegate::Save* GetSaveDelegate() const; virtual Profile* GetProfile() const; + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id); virtual WebContents* GetAsWebContents(); virtual void RenderViewCreated(RenderViewHost* render_view_host); virtual void RenderViewReady(RenderViewHost* render_view_host); diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index f69d623..01e7369 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -10,6 +10,8 @@ #include "chrome/common/page_transition_types.h" #include "webkit/glue/window_open_disposition.h" +class ExtensionFunctionDispatcher; +class RenderViewHost; class TabContents; class HtmlDialogUIDelegate; class GURL; @@ -149,6 +151,14 @@ class TabContentsDelegate { // is opened within if necessary. virtual void RenderWidgetShowing() {} + // This is used when the contents is an extension that needs to route + // api calls through to the Browser process. + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id) { + return NULL; + } + // This is called when webkit tells us that it is done tabbing through // controls on the page. Provides a way for TabContentsDelegates to handle // this. Returns true if the delegate successfully handled it. diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc index 3906d5b..a5bcfbb0 100644 --- a/chrome/browser/views/blocked_popup_container.cc +++ b/chrome/browser/views/blocked_popup_container.cc @@ -13,6 +13,7 @@ #include <math.h> #include "base/string_util.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gfx/chrome_canvas.h" @@ -393,6 +394,12 @@ TabContents* BlockedPopupContainer::GetConstrainingContents( return owner_; } +ExtensionFunctionDispatcher* BlockedPopupContainer:: + CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host, + const std::string& extension_id) { + return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id); +} + // Overridden from Animation: void BlockedPopupContainer::AnimateToState(double state) { if (in_show_animation_) diff --git a/chrome/browser/views/blocked_popup_container.h b/chrome/browser/views/blocked_popup_container.h index c634308..4a6fabe 100644 --- a/chrome/browser/views/blocked_popup_container.h +++ b/chrome/browser/views/blocked_popup_container.h @@ -185,6 +185,11 @@ class BlockedPopupContainer : public ConstrainedWindow, // Ignored; BlockedPopupContainer doesn't display a URL bar. virtual void UpdateTargetURL(TabContents* source, const GURL& url) { } + // Creates an ExtensionFunctionDispatcher that has no browser + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id); + // Overridden from Animation: // Changes the visibility percentage of the BlockedPopupContainer. This is diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc index 33a01c4..7c75d2f 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/views/tabs/dragged_tab_controller.cc @@ -8,6 +8,7 @@ #include <set> #include "chrome/browser/browser_window.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/views/frame/browser_view.h" @@ -396,6 +397,12 @@ void DraggedTabController::UpdateTargetURL(TabContents* source, // Ignored. } +ExtensionFunctionDispatcher* DraggedTabController:: + CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host, + const std::string& extension_id) { + return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id); +} + /////////////////////////////////////////////////////////////////////////////// // DraggedTabController, NotificationObserver implementation: diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h index 1989031..4406118 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.h +++ b/chrome/browser/views/tabs/dragged_tab_controller.h @@ -106,6 +106,11 @@ class DraggedTabController : public TabContentsDelegate, virtual void URLStarredChanged(TabContents* source, bool starred); virtual void UpdateTargetURL(TabContents* source, const GURL& url); + // Creates an ExtensionFunctionDispatcher that has no browser + virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher( + RenderViewHost* render_view_host, + const std::string& extension_id); + // Overridden from NotificationObserver: virtual void Observe(NotificationType type, const NotificationSource& source, diff --git a/chrome/browser/window_sizer.cc b/chrome/browser/window_sizer.cc index a3ec88d..ce34b71 100644 --- a/chrome/browser/window_sizer.cc +++ b/chrome/browser/window_sizer.cc @@ -88,8 +88,9 @@ class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider { // and persistent state from the browser window and the user's profile. class DefaultStateProvider : public WindowSizer::StateProvider { public: - explicit DefaultStateProvider(const std::wstring& app_name) - : app_name_(app_name) { + explicit DefaultStateProvider(const std::wstring& app_name, Browser* browser) + : app_name_(app_name), + browser_(browser) { } // Overridden from WindowSizer::StateProvider: @@ -125,24 +126,38 @@ class DefaultStateProvider : public WindowSizer::StateProvider { if (!app_name_.empty()) return false; - BrowserList::const_reverse_iterator it = BrowserList::begin_last_active(); - BrowserList::const_reverse_iterator end = BrowserList::end_last_active(); - for (; it != end; ++it) { - Browser* last_active = *it; - if (last_active && last_active->type() == Browser::TYPE_NORMAL) { - BrowserWindow* window = last_active->window(); - DCHECK(window); - *bounds = window->GetNormalBounds(); - return true; + // If a reference browser is set, use its window. Otherwise find last + // active. + BrowserWindow* window = NULL; + if (browser_) { + window = browser_->window(); + DCHECK(window); + } else { + BrowserList::const_reverse_iterator it = BrowserList::begin_last_active(); + BrowserList::const_reverse_iterator end = BrowserList::end_last_active(); + for (; (it != end); ++it) { + Browser* last_active = *it; + if (last_active && last_active->type() == Browser::TYPE_NORMAL) { + window = last_active->window(); + DCHECK(window); + break; + } } } + if (window) { + *bounds = window->GetNormalBounds(); + return true; + } + return false; } private: std::wstring app_name_; + // If set, is used as the reference browser for GetLastActiveWindowState. + Browser* browser_; DISALLOW_EVIL_CONSTRUCTORS(DefaultStateProvider); }; @@ -165,9 +180,10 @@ WindowSizer::~WindowSizer() { // static void WindowSizer::GetBrowserWindowBounds(const std::wstring& app_name, const gfx::Rect& specified_bounds, + Browser* browser, gfx::Rect* window_bounds, bool* maximized) { - const WindowSizer sizer(new DefaultStateProvider(app_name), + const WindowSizer sizer(new DefaultStateProvider(app_name, browser), new DefaultMonitorInfoProvider); sizer.DetermineWindowBounds(specified_bounds, window_bounds, maximized); } @@ -201,7 +217,7 @@ gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size) { // WindowSizer, private: WindowSizer::WindowSizer(const std::wstring& app_name) { - Init(new DefaultStateProvider(app_name), + Init(new DefaultStateProvider(app_name, NULL), new DefaultMonitorInfoProvider); } diff --git a/chrome/browser/window_sizer.h b/chrome/browser/window_sizer.h index cfdd129..5153f6d 100644 --- a/chrome/browser/window_sizer.h +++ b/chrome/browser/window_sizer.h @@ -10,6 +10,8 @@ #include "base/basictypes.h" #include "base/gfx/rect.h" +class Browser; + /////////////////////////////////////////////////////////////////////////////// // WindowSizer // @@ -91,9 +93,13 @@ class WindowSizer { }; // Determines the size, position and maximized state for the browser window. - // See documentation for DetermineWindowBounds below. + // See documentation for DetermineWindowBounds below. Normally, + // |window_bounds| is calculated by calling GetLastActiveWindowState(). To + // explicitly specify a particular window to base the bounds on, pass in a + // non-NULL value for |browser|. static void GetBrowserWindowBounds(const std::wstring& app_name, const gfx::Rect& specified_bounds, + Browser* browser, gfx::Rect* window_bounds, bool* maximized); diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc index 742d693..02024a3 100644 --- a/chrome/common/temp_scaffolding_stubs.cc +++ b/chrome/common/temp_scaffolding_stubs.cc @@ -275,6 +275,7 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) { void WindowSizer::GetBrowserWindowBounds(const std::wstring& app_name, const gfx::Rect& specified_bounds, + Browser* browser, gfx::Rect* window_bounds, bool* maximized) { // If we're given a bounds, use it (for things like tearing off tabs during diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h index 9edd9ff..c8d77fb 100644 --- a/chrome/common/temp_scaffolding_stubs.h +++ b/chrome/common/temp_scaffolding_stubs.h @@ -358,6 +358,7 @@ class WindowSizer { public: static void GetBrowserWindowBounds(const std::wstring& app_name, const gfx::Rect& specified_bounds, + Browser* browser, gfx::Rect* window_bounds, bool* maximized); }; diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index e84b725..75c7b54 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -10,6 +10,7 @@ var chromium; (function() { native function GetNextCallbackId(); + native function CreateWindow(); native function GetWindows(); native function GetTabsForWindow(); native function GetTab(); @@ -109,6 +110,25 @@ var chromium; }, chromium.types.optFun ]; + + chromium.tabs.createWindow = function(createData, callback) { + validate(arguments, arguments.callee.params); + sendRequest(CreateWindow, createData, callback); + }; + chromium.tabs.createWindow.params = [ + { + type: "object", + properties: { + url: chromium.types.optStr, + left: chromium.types.optInt, + top: chromium.types.optInt, + width: chromium.types.optPInt, + height: chromium.types.optPInt + }, + optional: true + }, + chromium.types.optFun + ]; // TODO(aa): This should eventually take an optional windowId param. chromium.tabs.getTabsForWindow = function(callback) { |