Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: components/dom_distiller/content/distiller_page_web_contents.cc

Issue 1058193002: Add support for not owning distilled WebContents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix issues. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/dom_distiller/content/distiller_page_web_contents.h" 5 #include "components/dom_distiller/content/distiller_page_web_contents.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "components/dom_distiller/content/web_contents_main_frame_observer.h" 10 #include "components/dom_distiller/content/web_contents_main_frame_observer.h"
11 #include "components/dom_distiller/core/distiller_page.h" 11 #include "components/dom_distiller/core/distiller_page.h"
12 #include "components/dom_distiller/core/dom_distiller_service.h" 12 #include "components/dom_distiller/core/dom_distiller_service.h"
13 #include "content/public/browser/browser_context.h" 13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/navigation_controller.h" 14 #include "content/public/browser/navigation_controller.h"
15 #include "content/public/browser/render_frame_host.h" 15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_view_host.h" 16 #include "content/public/browser/render_view_host.h"
17 #include "content/public/browser/web_contents.h" 17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_observer.h" 18 #include "content/public/browser/web_contents_observer.h"
19 #include "ui/gfx/screen.h" 19 #include "ui/gfx/screen.h"
20 #include "url/gurl.h" 20 #include "url/gurl.h"
21 21
22 namespace dom_distiller { 22 namespace dom_distiller {
23 23
24 SourcePageHandleWebContents::SourcePageHandleWebContents( 24 SourcePageHandleWebContents::SourcePageHandleWebContents(
25 scoped_ptr<content::WebContents> web_contents) 25 content::WebContents* web_contents,
26 : web_contents_(web_contents.Pass()) { 26 bool owned)
27 DCHECK(web_contents_); 27 : web_contents_(web_contents), owned_(owned) {
28 } 28 }
29 29
30 SourcePageHandleWebContents::~SourcePageHandleWebContents() { 30 SourcePageHandleWebContents::~SourcePageHandleWebContents() {
31 } 31 if (owned_) {
32 32 delete web_contents_;
33 scoped_ptr<content::WebContents> SourcePageHandleWebContents::GetWebContents() { 33 }
34 return web_contents_.Pass();
35 } 34 }
36 35
37 scoped_ptr<DistillerPage> DistillerPageWebContentsFactory::CreateDistillerPage( 36 scoped_ptr<DistillerPage> DistillerPageWebContentsFactory::CreateDistillerPage(
38 const gfx::Size& render_view_size) const { 37 const gfx::Size& render_view_size) const {
39 DCHECK(browser_context_); 38 DCHECK(browser_context_);
40 return scoped_ptr<DistillerPage>(new DistillerPageWebContents( 39 return scoped_ptr<DistillerPage>(new DistillerPageWebContents(
41 browser_context_, render_view_size, 40 browser_context_, render_view_size,
42 scoped_ptr<SourcePageHandleWebContents>())); 41 scoped_ptr<SourcePageHandleWebContents>()));
43 } 42 }
44 43
45 scoped_ptr<DistillerPage> 44 scoped_ptr<DistillerPage>
46 DistillerPageWebContentsFactory::CreateDistillerPageWithHandle( 45 DistillerPageWebContentsFactory::CreateDistillerPageWithHandle(
47 scoped_ptr<SourcePageHandle> handle) const { 46 scoped_ptr<SourcePageHandle> handle) const {
48 DCHECK(browser_context_); 47 DCHECK(browser_context_);
49 scoped_ptr<SourcePageHandleWebContents> web_contents_handle = 48 scoped_ptr<SourcePageHandleWebContents> web_contents_handle =
50 scoped_ptr<SourcePageHandleWebContents>( 49 scoped_ptr<SourcePageHandleWebContents>(
51 static_cast<SourcePageHandleWebContents*>(handle.release())); 50 static_cast<SourcePageHandleWebContents*>(handle.release()));
52 return scoped_ptr<DistillerPage>(new DistillerPageWebContents( 51 return scoped_ptr<DistillerPage>(new DistillerPageWebContents(
53 browser_context_, gfx::Size(), web_contents_handle.Pass())); 52 browser_context_, gfx::Size(), web_contents_handle.Pass()));
54 } 53 }
55 54
56 DistillerPageWebContents::DistillerPageWebContents( 55 DistillerPageWebContents::DistillerPageWebContents(
57 content::BrowserContext* browser_context, 56 content::BrowserContext* browser_context,
58 const gfx::Size& render_view_size, 57 const gfx::Size& render_view_size,
59 scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle) 58 scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle)
60 : state_(IDLE), browser_context_(browser_context), 59 : state_(IDLE),
60 source_page_handle_(nullptr),
61 browser_context_(browser_context),
61 render_view_size_(render_view_size) { 62 render_view_size_(render_view_size) {
62 if (optional_web_contents_handle) { 63 if (optional_web_contents_handle) {
63 web_contents_ = optional_web_contents_handle->GetWebContents().Pass(); 64 source_page_handle_ = optional_web_contents_handle.Pass();
64 if (render_view_size.IsEmpty()) 65 if (render_view_size.IsEmpty())
65 render_view_size_ = web_contents_->GetContainerBounds().size(); 66 render_view_size_ =
67 source_page_handle_->web_contents()->GetContainerBounds().size();
66 } 68 }
67 } 69 }
68 70
69 DistillerPageWebContents::~DistillerPageWebContents() { 71 DistillerPageWebContents::~DistillerPageWebContents() {
70 if (web_contents_)
71 web_contents_->SetDelegate(NULL);
72 } 72 }
73 73
74 bool DistillerPageWebContents::StringifyOutput() { 74 bool DistillerPageWebContents::StringifyOutput() {
75 return false; 75 return false;
76 } 76 }
77 77
78 bool DistillerPageWebContents::CreateNewContext() { 78 bool DistillerPageWebContents::CreateNewContext() {
79 return true; 79 return true;
80 } 80 }
81 81
82 void DistillerPageWebContents::DistillPageImpl(const GURL& url, 82 void DistillerPageWebContents::DistillPageImpl(const GURL& url,
83 const std::string& script) { 83 const std::string& script) {
84 DCHECK(browser_context_); 84 DCHECK(browser_context_);
85 DCHECK(state_ == IDLE); 85 DCHECK(state_ == IDLE);
86 state_ = LOADING_PAGE; 86 state_ = LOADING_PAGE;
87 script_ = script; 87 script_ = script;
88 88
89 if (web_contents_ && web_contents_->GetLastCommittedURL() == url) { 89 if (source_page_handle_ && source_page_handle_->web_contents() &&
90 source_page_handle_->web_contents()->GetLastCommittedURL() == url) {
90 WebContentsMainFrameObserver* main_frame_observer = 91 WebContentsMainFrameObserver* main_frame_observer =
91 WebContentsMainFrameObserver::FromWebContents(web_contents_.get()); 92 WebContentsMainFrameObserver::FromWebContents(
93 source_page_handle_->web_contents());
92 if (main_frame_observer && main_frame_observer->is_initialized()) { 94 if (main_frame_observer && main_frame_observer->is_initialized()) {
93 if (main_frame_observer->is_document_loaded_in_main_frame()) { 95 if (main_frame_observer->is_document_loaded_in_main_frame()) {
94 // Main frame has already loaded for the current WebContents, so execute 96 // Main frame has already loaded for the current WebContents, so execute
95 // JavaScript immediately. 97 // JavaScript immediately.
96 ExecuteJavaScript(); 98 ExecuteJavaScript();
97 } else { 99 } else {
98 // Main frame document has not loaded yet, so wait until it has before 100 // Main frame document has not loaded yet, so wait until it has before
99 // executing JavaScript. It will trigger after DocumentLoadedInFrame is 101 // executing JavaScript. It will trigger after DocumentLoadedInFrame is
100 // called for the main frame. 102 // called for the main frame.
101 content::WebContentsObserver::Observe(web_contents_.get()); 103 content::WebContentsObserver::Observe(
104 source_page_handle_->web_contents());
102 } 105 }
103 } else { 106 } else {
104 // The WebContentsMainFrameObserver has not been correctly initialized, 107 // The WebContentsMainFrameObserver has not been correctly initialized,
105 // so fall back to creating a new WebContents. 108 // so fall back to creating a new WebContents.
106 CreateNewWebContents(url); 109 CreateNewWebContents(url);
107 } 110 }
108 } else { 111 } else {
109 CreateNewWebContents(url); 112 CreateNewWebContents(url);
110 } 113 }
111 } 114 }
112 115
113 void DistillerPageWebContents::CreateNewWebContents(const GURL& url) { 116 void DistillerPageWebContents::CreateNewWebContents(const GURL& url) {
114 // Create new WebContents to use for distilling the content. 117 // Create new WebContents to use for distilling the content.
115 content::WebContents::CreateParams create_params(browser_context_); 118 content::WebContents::CreateParams create_params(browser_context_);
116 create_params.initially_hidden = true; 119 create_params.initially_hidden = true;
117 web_contents_.reset(content::WebContents::Create(create_params)); 120 content::WebContents* web_contents =
118 DCHECK(web_contents_.get()); 121 content::WebContents::Create(create_params);
122 DCHECK(web_contents);
119 123
120 web_contents_->SetDelegate(this); 124 web_contents->SetDelegate(this);
121 125
122 // Start observing WebContents and load the requested URL. 126 // Start observing WebContents and load the requested URL.
123 content::WebContentsObserver::Observe(web_contents_.get()); 127 content::WebContentsObserver::Observe(web_contents);
124 content::NavigationController::LoadURLParams params(url); 128 content::NavigationController::LoadURLParams params(url);
125 web_contents_->GetController().LoadURLWithParams(params); 129 web_contents->GetController().LoadURLWithParams(params);
130
131 source_page_handle_.reset(
132 new SourcePageHandleWebContents(web_contents, true));
126 } 133 }
127 134
128 gfx::Size DistillerPageWebContents::GetSizeForNewRenderView( 135 gfx::Size DistillerPageWebContents::GetSizeForNewRenderView(
129 content::WebContents* web_contents) const { 136 content::WebContents* web_contents) const {
130 gfx::Size size(render_view_size_); 137 gfx::Size size(render_view_size_);
131 if (size.IsEmpty()) 138 if (size.IsEmpty())
132 size = web_contents->GetContainerBounds().size(); 139 size = web_contents->GetContainerBounds().size();
133 // If size is still empty, set it to fullscreen so that document.offsetWidth 140 // If size is still empty, set it to fullscreen so that document.offsetWidth
134 // in the executed domdistiller.js won't be 0. 141 // in the executed domdistiller.js won't be 0.
135 if (size.IsEmpty()) { 142 if (size.IsEmpty()) {
136 DVLOG(1) << "Using fullscreen as default RenderView size"; 143 DVLOG(1) << "Using fullscreen as default RenderView size";
137 size = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().size(); 144 size = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().size();
138 } 145 }
139 return size; 146 return size;
140 } 147 }
141 148
142 void DistillerPageWebContents::DocumentLoadedInFrame( 149 void DistillerPageWebContents::DocumentLoadedInFrame(
143 content::RenderFrameHost* render_frame_host) { 150 content::RenderFrameHost* render_frame_host) {
144 if (render_frame_host == web_contents_->GetMainFrame()) { 151 if (render_frame_host ==
152 source_page_handle_->web_contents()->GetMainFrame()) {
145 ExecuteJavaScript(); 153 ExecuteJavaScript();
146 } 154 }
147 } 155 }
148 156
149 void DistillerPageWebContents::DidFailLoad( 157 void DistillerPageWebContents::DidFailLoad(
150 content::RenderFrameHost* render_frame_host, 158 content::RenderFrameHost* render_frame_host,
151 const GURL& validated_url, 159 const GURL& validated_url,
152 int error_code, 160 int error_code,
153 const base::string16& error_description) { 161 const base::string16& error_description) {
154 if (!render_frame_host->GetParent()) { 162 if (!render_frame_host->GetParent()) {
155 content::WebContentsObserver::Observe(NULL); 163 content::WebContentsObserver::Observe(NULL);
156 DCHECK(state_ == LOADING_PAGE || state_ == EXECUTING_JAVASCRIPT); 164 DCHECK(state_ == LOADING_PAGE || state_ == EXECUTING_JAVASCRIPT);
157 state_ = PAGELOAD_FAILED; 165 state_ = PAGELOAD_FAILED;
158 scoped_ptr<base::Value> empty(base::Value::CreateNullValue()); 166 scoped_ptr<base::Value> empty(base::Value::CreateNullValue());
159 OnWebContentsDistillationDone(GURL(), empty.get()); 167 OnWebContentsDistillationDone(GURL(), empty.get());
160 } 168 }
161 } 169 }
162 170
163 void DistillerPageWebContents::ExecuteJavaScript() { 171 void DistillerPageWebContents::ExecuteJavaScript() {
164 content::RenderFrameHost* frame = web_contents_->GetMainFrame(); 172 content::RenderFrameHost* frame =
173 source_page_handle_->web_contents()->GetMainFrame();
165 DCHECK(frame); 174 DCHECK(frame);
166 DCHECK_EQ(LOADING_PAGE, state_); 175 DCHECK_EQ(LOADING_PAGE, state_);
167 state_ = EXECUTING_JAVASCRIPT; 176 state_ = EXECUTING_JAVASCRIPT;
168 content::WebContentsObserver::Observe(NULL); 177 content::WebContentsObserver::Observe(NULL);
169 web_contents_->Stop(); 178 // Stop any pending navigation since the intent is to distill the current
179 // page.
180 source_page_handle_->web_contents()->Stop();
170 DVLOG(1) << "Beginning distillation"; 181 DVLOG(1) << "Beginning distillation";
171 frame->ExecuteJavaScript( 182 frame->ExecuteJavaScript(
172 base::UTF8ToUTF16(script_), 183 base::UTF8ToUTF16(script_),
173 base::Bind(&DistillerPageWebContents::OnWebContentsDistillationDone, 184 base::Bind(&DistillerPageWebContents::OnWebContentsDistillationDone,
174 base::Unretained(this), 185 base::Unretained(this),
175 web_contents_->GetLastCommittedURL())); 186 source_page_handle_->web_contents()->GetLastCommittedURL()));
176 } 187 }
177 188
178 void DistillerPageWebContents::OnWebContentsDistillationDone( 189 void DistillerPageWebContents::OnWebContentsDistillationDone(
179 const GURL& page_url, 190 const GURL& page_url,
180 const base::Value* value) { 191 const base::Value* value) {
181 DCHECK(state_ == PAGELOAD_FAILED || state_ == EXECUTING_JAVASCRIPT); 192 DCHECK(state_ == PAGELOAD_FAILED || state_ == EXECUTING_JAVASCRIPT);
182 state_ = IDLE; 193 state_ = IDLE;
183 DistillerPage::OnDistillationDone(page_url, value); 194 DistillerPage::OnDistillationDone(page_url, value);
184 } 195 }
185 196
186 } // namespace dom_distiller 197 } // namespace dom_distiller
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698