Commit b00e2341 authored by flackr@chromium.org's avatar flackr@chromium.org

Handle WebContents created for new windows and create activities for these.

BUG=391473
TEST=Follow a link from Gmail or hold shift when clicking a link. A new activity following the link is created.

Review URL: https://codereview.chromium.org/398603002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285049 0039d316-1c4b-4281-b951-d872f2087c98
parent e8696c3b
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "athena/content/web_activity.h" #include "athena/content/web_activity.h"
#include "athena/activity/public/activity_factory.h"
#include "athena/activity/public/activity_manager.h" #include "athena/activity/public/activity_manager.h"
#include "athena/input/public/accelerator_manager.h" #include "athena/input/public/accelerator_manager.h"
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/controls/webview/webview.h" #include "ui/views/controls/webview/webview.h"
#include "ui/views/focus/focus_manager.h" #include "ui/views/focus/focus_manager.h"
...@@ -124,32 +127,30 @@ class AthenaWebView : public views::WebView { ...@@ -124,32 +127,30 @@ class AthenaWebView : public views::WebView {
public: public:
AthenaWebView(content::BrowserContext* context) AthenaWebView(content::BrowserContext* context)
: views::WebView(context), controller_(new WebActivityController(this)) { : views::WebView(context), controller_(new WebActivityController(this)) {
// We create the first web contents ourselves to allow us to replace it
// later on.
SetWebContents(content::WebContents::Create(
content::WebContents::CreateParams(context)));
// TODO(skuhne): Add content observer to detect renderer crash and set // TODO(skuhne): Add content observer to detect renderer crash and set
// content status to unloaded if that happens. // content status to unloaded if that happens.
} }
virtual ~AthenaWebView() {
// |WebView| does not own the content, so we need to destroy it here. AthenaWebView(content::WebContents* web_contents)
content::WebContents* current_contents = GetWebContents(); : views::WebView(web_contents->GetBrowserContext()),
SetWebContents(NULL); controller_(new WebActivityController(this)) {
delete current_contents; scoped_ptr<content::WebContents> old_contents(
SwapWebContents(scoped_ptr<content::WebContents>(web_contents)));
} }
virtual ~AthenaWebView() {}
void InstallAccelerators() { controller_->InstallAccelerators(); } void InstallAccelerators() { controller_->InstallAccelerators(); }
void EvictContent() { void EvictContent() {
content::WebContents* old_contents = GetWebContents(); scoped_ptr<content::WebContents> old_contents(SwapWebContents(
scoped_ptr<content::WebContents>(content::WebContents::Create(
content::WebContents::CreateParams(browser_context())))));
evicted_web_contents_.reset( evicted_web_contents_.reset(
content::WebContents::Create(content::WebContents::CreateParams( content::WebContents::Create(content::WebContents::CreateParams(
old_contents->GetBrowserContext()))); old_contents->GetBrowserContext())));
evicted_web_contents_->GetController().CopyStateFrom( evicted_web_contents_->GetController().CopyStateFrom(
old_contents->GetController()); old_contents->GetController());
SetWebContents(content::WebContents::Create(
content::WebContents::CreateParams(old_contents->GetBrowserContext())));
delete old_contents;
// As soon as the new contents becomes visible, it should reload. // As soon as the new contents becomes visible, it should reload.
// TODO(skuhne): This breaks script connections with other activities. // TODO(skuhne): This breaks script connections with other activities.
// Even though this is the same technique as used by the TabStripModel, // Even though this is the same technique as used by the TabStripModel,
...@@ -159,16 +160,60 @@ class AthenaWebView : public views::WebView { ...@@ -159,16 +160,60 @@ class AthenaWebView : public views::WebView {
void ReloadContent() { void ReloadContent() {
CHECK(evicted_web_contents_.get()); CHECK(evicted_web_contents_.get());
content::WebContents* null_contents = GetWebContents(); scoped_ptr<content::WebContents> replaced_contents(SwapWebContents(
SetWebContents(evicted_web_contents_.release()); evicted_web_contents_.Pass()));
delete null_contents;
} }
// Check if the content got evicted. // Check if the content got evicted.
const bool IsContentEvicted() { return !!evicted_web_contents_.get(); } const bool IsContentEvicted() { return !!evicted_web_contents_.get(); }
private: // content::WebContentsDelegate:
// WebContentsDelegate: virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE {
switch(params.disposition) {
case CURRENT_TAB: {
DCHECK(source == web_contents());
content::NavigationController::LoadURLParams load_url_params(
params.url);
load_url_params.referrer = params.referrer;
load_url_params.frame_tree_node_id = params.frame_tree_node_id;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
web_contents()->GetController().LoadURLWithParams(load_url_params);
return web_contents();
}
case NEW_FOREGROUND_TAB:
case NEW_BACKGROUND_TAB:
case NEW_POPUP:
case NEW_WINDOW: {
ActivityManager::Get()->AddActivity(
ActivityFactory::Get()->CreateWebActivity(browser_context(),
params.url));
break;
}
default:
break;
}
// NULL is returned if the URL wasn't opened immediately.
return NULL;
}
virtual void AddNewContents(content::WebContents* source,
content::WebContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) OVERRIDE {
ActivityManager::Get()->AddActivity(
new WebActivity(new AthenaWebView(new_contents)));
}
virtual bool PreHandleKeyboardEvent( virtual bool PreHandleKeyboardEvent(
content::WebContents* source, content::WebContents* source,
const content::NativeWebKeyboardEvent& event, const content::NativeWebKeyboardEvent& event,
...@@ -183,6 +228,7 @@ class AthenaWebView : public views::WebView { ...@@ -183,6 +228,7 @@ class AthenaWebView : public views::WebView {
controller_->HandleKeyboardEvent(source, event); controller_->HandleKeyboardEvent(source, event);
} }
private:
scoped_ptr<WebActivityController> controller_; scoped_ptr<WebActivityController> controller_;
// If the activity got evicted, this is the web content which holds the known // If the activity got evicted, this is the web content which holds the known
...@@ -200,6 +246,16 @@ WebActivity::WebActivity(content::BrowserContext* browser_context, ...@@ -200,6 +246,16 @@ WebActivity::WebActivity(content::BrowserContext* browser_context,
current_state_(ACTIVITY_UNLOADED) { current_state_(ACTIVITY_UNLOADED) {
} }
WebActivity::WebActivity(AthenaWebView* web_view)
: browser_context_(web_view->browser_context()),
url_(web_view->GetWebContents()->GetURL()),
web_view_(web_view),
current_state_(ACTIVITY_UNLOADED) {
// Transition to state ACTIVITY_INVISIBLE to perform the same setup steps
// as on new activities (namely adding a WebContentsObserver).
SetCurrentState(ACTIVITY_INVISIBLE);
}
WebActivity::~WebActivity() { WebActivity::~WebActivity() {
// It is not required to change the activity state to UNLOADED - unless we // It is not required to change the activity state to UNLOADED - unless we
// would add state observers. // would add state observers.
......
...@@ -29,6 +29,7 @@ class WebActivity : public Activity, ...@@ -29,6 +29,7 @@ class WebActivity : public Activity,
public content::WebContentsObserver { public content::WebContentsObserver {
public: public:
WebActivity(content::BrowserContext* context, const GURL& gurl); WebActivity(content::BrowserContext* context, const GURL& gurl);
WebActivity(AthenaWebView* web_view);
virtual ~WebActivity(); virtual ~WebActivity();
protected: protected:
......
...@@ -122,6 +122,18 @@ ui::TextInputClient* WebView::GetTextInputClient() { ...@@ -122,6 +122,18 @@ ui::TextInputClient* WebView::GetTextInputClient() {
return NULL; return NULL;
} }
scoped_ptr<content::WebContents> WebView::SwapWebContents(
scoped_ptr<content::WebContents> new_web_contents) {
if (wc_owner_)
wc_owner_->SetDelegate(NULL);
scoped_ptr<content::WebContents> old_web_contents(wc_owner_.Pass());
wc_owner_ = new_web_contents.Pass();
if (wc_owner_)
wc_owner_->SetDelegate(this);
SetWebContents(wc_owner_.get());
return old_web_contents.Pass();
}
void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
// In most cases, the holder is simply sized to fill this WebView's bounds. // In most cases, the holder is simply sized to fill this WebView's bounds.
// Only WebContentses that are in fullscreen mode and being screen-captured // Only WebContentses that are in fullscreen mode and being screen-captured
......
...@@ -97,6 +97,11 @@ class WEBVIEW_EXPORT WebView : public View, ...@@ -97,6 +97,11 @@ class WEBVIEW_EXPORT WebView : public View,
virtual ui::TextInputClient* GetTextInputClient() OVERRIDE; virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
protected: protected:
// Swaps the owned WebContents |wc_owner_| with |new_web_contents|. Returns
// the previously owned WebContents.
scoped_ptr<content::WebContents> SwapWebContents(
scoped_ptr<content::WebContents> new_web_contents);
// Overridden from View: // Overridden from View:
virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
virtual void ViewHierarchyChanged( virtual void ViewHierarchyChanged(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment