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

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

Issue 341563002: Theme Preferences for Distilled Pages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor changes Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/dom_distiller_viewer_source.h" 5 #include "components/dom_distiller/content/dom_distiller_viewer_source.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/memory/ref_counted_memory.h" 11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "components/dom_distiller/core/dom_distiller_service.h"
16 #include "components/dom_distiller/core/reader_mode_preferences.h"
15 #include "components/dom_distiller/core/task_tracker.h" 17 #include "components/dom_distiller/core/task_tracker.h"
16 #include "components/dom_distiller/core/url_constants.h" 18 #include "components/dom_distiller/core/url_constants.h"
17 #include "components/dom_distiller/core/viewer.h" 19 #include "components/dom_distiller/core/viewer.h"
18 #include "content/public/browser/navigation_details.h" 20 #include "content/public/browser/navigation_details.h"
19 #include "content/public/browser/navigation_entry.h" 21 #include "content/public/browser/navigation_entry.h"
20 #include "content/public/browser/render_frame_host.h" 22 #include "content/public/browser/render_frame_host.h"
21 #include "content/public/browser/render_view_host.h" 23 #include "content/public/browser/render_view_host.h"
22 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_observer.h" 25 #include "content/public/browser/web_contents_observer.h"
24 #include "net/base/url_util.h" 26 #include "net/base/url_util.h"
25 #include "net/url_request/url_request.h" 27 #include "net/url_request/url_request.h"
26 28
27 namespace dom_distiller { 29 namespace dom_distiller {
28 30
29 // Handles receiving data asynchronously for a specific entry, and passing 31 // Handles receiving data asynchronously for a specific entry, and passing
30 // it along to the data callback for the data source. Lifetime matches that of 32 // it along to the data callback for the data source. Lifetime matches that of
31 // the current main frame's page in the Viewer instance. 33 // the current main frame's page in the Viewer instance.
32 class DomDistillerViewerSource::RequestViewerHandle 34 class DomDistillerViewerSource::RequestViewerHandle
33 : public ViewRequestDelegate, 35 : public ViewRequestDelegate,
34 public content::WebContentsObserver { 36 public content::WebContentsObserver,
37 public ReaderModePrefs::Observer {
35 public: 38 public:
36 explicit RequestViewerHandle( 39 explicit RequestViewerHandle(
37 content::WebContents* web_contents, 40 content::WebContents* web_contents,
38 const std::string& expected_scheme, 41 const std::string& expected_scheme,
39 const std::string& expected_request_path, 42 const std::string& expected_request_path,
40 const content::URLDataSource::GotDataCallback& callback); 43 const content::URLDataSource::GotDataCallback& callback,
44 ReaderModePrefs* reader_mode_prefs);
41 virtual ~RequestViewerHandle(); 45 virtual ~RequestViewerHandle();
42 46
43 // ViewRequestDelegate implementation. 47 // ViewRequestDelegate implementation:
44 virtual void OnArticleReady( 48 virtual void OnArticleReady(
45 const DistilledArticleProto* article_proto) OVERRIDE; 49 const DistilledArticleProto* article_proto) OVERRIDE;
46 50
47 virtual void OnArticleUpdated( 51 virtual void OnArticleUpdated(
48 ArticleDistillationUpdate article_update) OVERRIDE; 52 ArticleDistillationUpdate article_update) OVERRIDE;
49 53
50 void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle); 54 void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle);
51 55
52 // WebContentsObserver: 56 // content::WebContentsObserver implementation:
53 virtual void DidNavigateMainFrame( 57 virtual void DidNavigateMainFrame(
54 const content::LoadCommittedDetails& details, 58 const content::LoadCommittedDetails& details,
55 const content::FrameNavigateParams& params) OVERRIDE; 59 const content::FrameNavigateParams& params) OVERRIDE;
56 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; 60 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
57 virtual void WebContentsDestroyed() OVERRIDE; 61 virtual void WebContentsDestroyed() OVERRIDE;
58 virtual void DidFinishLoad( 62 virtual void DidFinishLoad(
59 int64 frame_id, 63 int64 frame_id,
60 const GURL& validated_url, 64 const GURL& validated_url,
61 bool is_main_frame, 65 bool is_main_frame,
62 content::RenderViewHost* render_view_host) OVERRIDE; 66 content::RenderViewHost* render_view_host) OVERRIDE;
63 67
68 // Needed by DomDistillerViewerSource.
69 const ReaderModePrefs* GetReaderModePrefs();
nyquist 2014/06/27 20:48:26 Remove.
smaslo 2014/06/30 17:57:14 It removed it, but I had to make the reader_mode_p
70
64 private: 71 private:
65 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't 72 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't
66 // ready. 73 // ready.
67 void SendJavaScript(const std::string& buffer); 74 void SendJavaScript(const std::string& buffer);
68 75
69 // Cancels the current view request. Once called, no updates will be 76 // Cancels the current view request. Once called, no updates will be
70 // propagated to the view, and the request to DomDistillerService will be 77 // propagated to the view, and the request to DomDistillerService will be
71 // cancelled. 78 // cancelled.
72 void Cancel(); 79 void Cancel();
73 80
81 // ReaderModePrefs::Observer implementation:
82 virtual void OnChangeTheme(ReaderModePrefs::Theme new_theme) OVERRIDE;
83
84 // Sets CSS class name for the webpage's HTML body element.
nyquist 2014/06/27 20:48:26 Remove
smaslo 2014/06/30 17:57:14 Done.
85 void SetBodyClassName();
86
74 // The handle to the view request towards the DomDistillerService. It 87 // The handle to the view request towards the DomDistillerService. It
75 // needs to be kept around to ensure the distillation request finishes. 88 // needs to be kept around to ensure the distillation request finishes.
76 scoped_ptr<ViewerHandle> viewer_handle_; 89 scoped_ptr<ViewerHandle> viewer_handle_;
77 90
78 // WebContents associated with the Viewer's render process. 91 // WebContents associated with the Viewer's render process.
79 content::WebContents* web_contents_; 92 content::WebContents* web_contents_;
80 93
81 // The scheme hosting the current view request; 94 // The scheme hosting the current view request;
82 std::string expected_scheme_; 95 std::string expected_scheme_;
83 96
84 // The query path for the current view request. 97 // The query path for the current view request.
85 std::string expected_request_path_; 98 std::string expected_request_path_;
86 99
87 // Holds the callback to where the data retrieved is sent back. 100 // Holds the callback to where the data retrieved is sent back.
88 content::URLDataSource::GotDataCallback callback_; 101 content::URLDataSource::GotDataCallback callback_;
89 102
90 // Number of pages of the distilled article content that have been rendered by 103 // Number of pages of the distilled article content that have been rendered by
91 // the viewer. 104 // the viewer.
92 int page_count_; 105 int page_count_;
93 106
94 // Whether the page is sufficiently initialized to handle updates from the 107 // Whether the page is sufficiently initialized to handle updates from the
95 // distiller. 108 // distiller.
96 bool waiting_for_page_ready_; 109 bool waiting_for_page_ready_;
97 110
98 // Temporary store of pending JavaScript if the page isn't ready to receive 111 // Temporary store of pending JavaScript if the page isn't ready to receive
99 // data from distillation. 112 // data from distillation.
100 std::string buffer_; 113 std::string buffer_;
114
115 // Interface for accessing preferences for reader mode.
116 ReaderModePrefs* reader_mode_prefs_;
101 }; 117 };
102 118
103 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( 119 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
104 content::WebContents* web_contents, 120 content::WebContents* web_contents,
105 const std::string& expected_scheme, 121 const std::string& expected_scheme,
106 const std::string& expected_request_path, 122 const std::string& expected_request_path,
107 const content::URLDataSource::GotDataCallback& callback) 123 const content::URLDataSource::GotDataCallback& callback,
124 ReaderModePrefs* reader_mode_prefs)
108 : web_contents_(web_contents), 125 : web_contents_(web_contents),
109 expected_scheme_(expected_scheme), 126 expected_scheme_(expected_scheme),
110 expected_request_path_(expected_request_path), 127 expected_request_path_(expected_request_path),
111 callback_(callback), 128 callback_(callback),
112 page_count_(0), 129 page_count_(0),
113 waiting_for_page_ready_(true) { 130 waiting_for_page_ready_(true),
131 reader_mode_prefs_(reader_mode_prefs) {
114 content::WebContentsObserver::Observe(web_contents_); 132 content::WebContentsObserver::Observe(web_contents_);
133 reader_mode_prefs_->AddObserver(this);
115 } 134 }
116 135
117 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { 136 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
118 // Balanced with constructor although can be a no-op if frame navigated away. 137 // Balanced with constructor although can be a no-op if frame navigated away.
119 content::WebContentsObserver::Observe(NULL); 138 content::WebContentsObserver::Observe(NULL);
139 reader_mode_prefs_->RemoveObserver(this);
120 } 140 }
121 141
122 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript( 142 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript(
123 const std::string& buffer) { 143 const std::string& buffer) {
124 if (waiting_for_page_ready_) { 144 if (waiting_for_page_ready_) {
125 buffer_ += buffer; 145 buffer_ += buffer;
126 } else { 146 } else {
127 if (web_contents_) { 147 if (web_contents_) {
128 web_contents_->GetMainFrame()->ExecuteJavaScript( 148 web_contents_->GetMainFrame()->ExecuteJavaScript(
129 base::UTF8ToUTF16(buffer)); 149 base::UTF8ToUTF16(buffer));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 web_contents_->GetMainFrame()->ExecuteJavaScript( 203 web_contents_->GetMainFrame()->ExecuteJavaScript(
184 base::UTF8ToUTF16(buffer_)); 204 base::UTF8ToUTF16(buffer_));
185 } 205 }
186 buffer_.clear(); 206 buffer_.clear();
187 } 207 }
188 208
189 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady( 209 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady(
190 const DistilledArticleProto* article_proto) { 210 const DistilledArticleProto* article_proto) {
191 if (page_count_ == 0) { 211 if (page_count_ == 0) {
192 // This is a single-page article. 212 // This is a single-page article.
193 std::string unsafe_page_html = viewer::GetUnsafeArticleHtml(article_proto); 213 std::string unsafe_page_html = viewer::GetUnsafeArticleHtml(article_proto,
214 reader_mode_prefs_->GetThemePref());
194 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); 215 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
195 } else if (page_count_ == article_proto->pages_size()) { 216 } else if (page_count_ == article_proto->pages_size()) {
196 // We may still be showing the "Loading" indicator. 217 // We may still be showing the "Loading" indicator.
197 SendJavaScript(viewer::GetToggleLoadingIndicatorJs(true)); 218 SendJavaScript(viewer::GetToggleLoadingIndicatorJs(true));
198 } else { 219 } else {
199 // It's possible that we didn't get some incremental updates from the 220 // It's possible that we didn't get some incremental updates from the
200 // distiller. Ensure all remaining pages are flushed to the viewer. 221 // distiller. Ensure all remaining pages are flushed to the viewer.
201 for (;page_count_ < article_proto->pages_size(); page_count_++) { 222 for (;page_count_ < article_proto->pages_size(); page_count_++) {
202 const DistilledPageProto& page = article_proto->pages(page_count_); 223 const DistilledPageProto& page = article_proto->pages(page_count_);
203 SendJavaScript( 224 SendJavaScript(
204 viewer::GetUnsafeIncrementalDistilledPageJs( 225 viewer::GetUnsafeIncrementalDistilledPageJs(
205 &page, 226 &page,
206 page_count_ == article_proto->pages_size())); 227 page_count_ == article_proto->pages_size()));
207 } 228 }
208 } 229 }
209 // No need to hold on to the ViewerHandle now that distillation is complete. 230 // No need to hold on to the ViewerHandle now that distillation is complete.
210 viewer_handle_.reset(); 231 viewer_handle_.reset();
211 } 232 }
212 233
213 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated( 234 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated(
214 ArticleDistillationUpdate article_update) { 235 ArticleDistillationUpdate article_update) {
215 for (;page_count_ < static_cast<int>(article_update.GetPagesSize()); 236 for (;page_count_ < static_cast<int>(article_update.GetPagesSize());
216 page_count_++) { 237 page_count_++) {
217 const DistilledPageProto& page = 238 const DistilledPageProto& page =
218 article_update.GetDistilledPage(page_count_); 239 article_update.GetDistilledPage(page_count_);
219 if (page_count_ == 0) { 240 if (page_count_ == 0) {
220 // This is the first page, so send Viewer page scaffolding too. 241 // This is the first page, so send Viewer page scaffolding too.
221 std::string unsafe_page_html = viewer::GetUnsafePartialArticleHtml(&page); 242 std::string unsafe_page_html = viewer::GetUnsafePartialArticleHtml(&page,
243 reader_mode_prefs_->GetThemePref());
222 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); 244 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
223 } else { 245 } else {
224 SendJavaScript( 246 SendJavaScript(
225 viewer::GetUnsafeIncrementalDistilledPageJs(&page, false)); 247 viewer::GetUnsafeIncrementalDistilledPageJs(&page, false));
226 } 248 }
227 } 249 }
228 } 250 }
229 251
230 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle( 252 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle(
231 scoped_ptr<ViewerHandle> viewer_handle) { 253 scoped_ptr<ViewerHandle> viewer_handle) {
232 viewer_handle_ = viewer_handle.Pass(); 254 viewer_handle_ = viewer_handle.Pass();
233 } 255 }
234 256
257 void DomDistillerViewerSource::RequestViewerHandle::OnChangeTheme(
258 ReaderModePrefs::Theme theme) {
nyquist 2014/06/27 20:48:26 Nit: new_theme
smaslo 2014/06/30 17:57:14 Done.
259 SetBodyClassName();
nyquist 2014/06/27 20:48:26 This is the only place that method is used, so jus
smaslo 2014/06/30 17:57:14 Done.
260 }
261
262 void DomDistillerViewerSource::RequestViewerHandle::SetBodyClassName() {
nyquist 2014/06/27 20:48:26 Require theme as argument: ReaderModePrefs::Theme
smaslo 2014/06/30 17:57:14 Done.
263 std::ostringstream js;
264 js << "document.body.className='" <<
265 viewer::GetBodyCssClass(reader_mode_prefs_->GetThemePref()) << "';";
266 SendJavaScript(js.str());
267 }
268
269 const ReaderModePrefs* DomDistillerViewerSource::RequestViewerHandle::
nyquist 2014/06/27 20:48:26 Remove.
smaslo 2014/06/30 17:57:14 Done.
270 GetReaderModePrefs() {
271 return reader_mode_prefs_;
272 }
273
235 DomDistillerViewerSource::DomDistillerViewerSource( 274 DomDistillerViewerSource::DomDistillerViewerSource(
236 DomDistillerServiceInterface* dom_distiller_service, 275 DomDistillerServiceInterface* dom_distiller_service,
237 const std::string& scheme) 276 const std::string& scheme)
238 : scheme_(scheme), dom_distiller_service_(dom_distiller_service) { 277 : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {
239 } 278 }
240 279
241 DomDistillerViewerSource::~DomDistillerViewerSource() { 280 DomDistillerViewerSource::~DomDistillerViewerSource() {
242 } 281 }
243 282
244 std::string DomDistillerViewerSource::GetSource() const { 283 std::string DomDistillerViewerSource::GetSource() const {
(...skipping 26 matching lines...) Expand all
271 content::WebContents* web_contents = 310 content::WebContents* web_contents =
272 content::WebContents::FromRenderFrameHost( 311 content::WebContents::FromRenderFrameHost(
273 content::RenderFrameHost::FromID(render_process_id, 312 content::RenderFrameHost::FromID(render_process_id,
274 render_frame_id)); 313 render_frame_id));
275 DCHECK(web_contents); 314 DCHECK(web_contents);
276 // An empty |path| is invalid, but guard against it. If not empty, assume 315 // An empty |path| is invalid, but guard against it. If not empty, assume
277 // |path| starts with '?', which is stripped away. 316 // |path| starts with '?', which is stripped away.
278 const std::string path_after_query_separator = 317 const std::string path_after_query_separator =
279 path.size() > 0 ? path.substr(1) : ""; 318 path.size() > 0 ? path.substr(1) : "";
280 RequestViewerHandle* request_viewer_handle = new RequestViewerHandle( 319 RequestViewerHandle* request_viewer_handle = new RequestViewerHandle(
281 web_contents, scheme_, path_after_query_separator, callback); 320 web_contents, scheme_, path_after_query_separator, callback,
321 dom_distiller_service_->GetReaderModePrefs());
282 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( 322 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
283 dom_distiller_service_, path, request_viewer_handle); 323 dom_distiller_service_, path, request_viewer_handle);
284 324
285 if (viewer_handle) { 325 if (viewer_handle) {
286 // The service returned a |ViewerHandle| and guarantees it will call 326 // The service returned a |ViewerHandle| and guarantees it will call
287 // the |RequestViewerHandle|, so passing ownership to it, to ensure the 327 // the |RequestViewerHandle|, so passing ownership to it, to ensure the
288 // request is not cancelled. The |RequestViewerHandle| will delete itself 328 // request is not cancelled. The |RequestViewerHandle| will delete itself
289 // after receiving the callback. 329 // after receiving the callback.
290 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); 330 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass());
291 } else { 331 } else {
332 std::string error_page_html = viewer::GetErrorPageHtml(
333 request_viewer_handle->GetReaderModePrefs()->GetThemePref());
292 // The service did not return a |ViewerHandle|, which means the 334 // The service did not return a |ViewerHandle|, which means the
nyquist 2014/06/27 20:48:26 Just get it from the service like you do above. Th
smaslo 2014/06/30 17:57:14 Done.
293 // |RequestViewerHandle| will never be called, so clean up now. 335 // |RequestViewerHandle| will never be called, so clean up now.
294 delete request_viewer_handle; 336 delete request_viewer_handle;
295
296 std::string error_page_html = viewer::GetErrorPageHtml();
297 callback.Run(base::RefCountedString::TakeString(&error_page_html)); 337 callback.Run(base::RefCountedString::TakeString(&error_page_html));
298 } 338 }
299 }; 339 };
300 340
301 std::string DomDistillerViewerSource::GetMimeType( 341 std::string DomDistillerViewerSource::GetMimeType(
302 const std::string& path) const { 342 const std::string& path) const {
303 if (kViewerCssPath == path) { 343 if (kViewerCssPath == path) {
304 return "text/css"; 344 return "text/css";
305 } 345 }
306 if (kViewerJsPath == path) { 346 if (kViewerJsPath == path) {
(...skipping 12 matching lines...) Expand all
319 const net::URLRequest* request, 359 const net::URLRequest* request,
320 std::string* path) const { 360 std::string* path) const {
321 } 361 }
322 362
323 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() 363 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc()
324 const { 364 const {
325 return "object-src 'none'; style-src 'self';"; 365 return "object-src 'none'; style-src 'self';";
326 } 366 }
327 367
328 } // namespace dom_distiller 368 } // namespace dom_distiller
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698