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

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

Issue 235833003: Move helper utilities for the DOM Distiller Viewer to core. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed iOS grit whitelist Created 6 years, 8 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/string_util.h"
15 #include "components/dom_distiller/core/dom_distiller_service.h"
16 #include "components/dom_distiller/core/proto/distilled_article.pb.h"
17 #include "components/dom_distiller/core/proto/distilled_page.pb.h"
18 #include "components/dom_distiller/core/task_tracker.h" 14 #include "components/dom_distiller/core/task_tracker.h"
19 #include "components/dom_distiller/core/url_constants.h" 15 #include "components/dom_distiller/core/url_constants.h"
20 #include "components/dom_distiller/core/url_utils.h" 16 #include "components/dom_distiller/core/viewer.h"
21 #include "content/public/browser/render_frame_host.h" 17 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/render_view_host.h" 18 #include "content/public/browser/render_view_host.h"
23 #include "grit/component_resources.h"
24 #include "grit/component_strings.h"
25 #include "net/base/escape.h"
26 #include "net/url_request/url_request.h" 19 #include "net/url_request/url_request.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "url/gurl.h"
30 20
31 namespace dom_distiller { 21 namespace dom_distiller {
32 22
33 namespace {
34
35 std::string ReplaceHtmlTemplateValues(const std::string& title,
36 const std::string& content,
37 const std::string& original_url) {
38 base::StringPiece html_template =
39 ResourceBundle::GetSharedInstance().GetRawDataResource(
40 IDR_DOM_DISTILLER_VIEWER_HTML);
41 std::vector<std::string> substitutions;
42 substitutions.push_back(title); // $1
43 substitutions.push_back(kCssPath); // $2
44 substitutions.push_back(title); // $3
45 substitutions.push_back(content); // $4
46 substitutions.push_back(original_url); // $5
47 substitutions.push_back(
48 l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_VIEW_ORIGINAL)); // $6
49 return ReplaceStringPlaceholders(html_template, substitutions, NULL);
50 }
51
52 } // namespace
53
54 // Handles receiving data asynchronously for a specific entry, and passing 23 // Handles receiving data asynchronously for a specific entry, and passing
55 // it along to the data callback for the data source. 24 // it along to the data callback for the data source.
56 class DomDistillerViewerSource::RequestViewerHandle 25 class DomDistillerViewerSource::RequestViewerHandle
57 : public ViewRequestDelegate { 26 : public ViewRequestDelegate {
58 public: 27 public:
59 explicit RequestViewerHandle( 28 explicit RequestViewerHandle(
60 const content::URLDataSource::GotDataCallback& callback); 29 const content::URLDataSource::GotDataCallback& callback);
61 virtual ~RequestViewerHandle(); 30 virtual ~RequestViewerHandle();
62 31
63 // ViewRequestDelegate implementation. 32 // ViewRequestDelegate implementation.
64 virtual void OnArticleReady(const DistilledArticleProto* article_proto) 33 virtual void OnArticleReady(
65 OVERRIDE; 34 const DistilledArticleProto* article_proto) OVERRIDE;
66 35
67 virtual void OnArticleUpdated(ArticleDistillationUpdate article_update) 36 virtual void OnArticleUpdated(
68 OVERRIDE; 37 ArticleDistillationUpdate article_update) OVERRIDE;
69 38
70 void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle); 39 void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle);
71 40
72 private: 41 private:
73 // The handle to the view request towards the DomDistillerService. It 42 // The handle to the view request towards the DomDistillerService. It
74 // needs to be kept around to ensure the distillation request finishes. 43 // needs to be kept around to ensure the distillation request finishes.
75 scoped_ptr<ViewerHandle> viewer_handle_; 44 scoped_ptr<ViewerHandle> viewer_handle_;
76 45
77 // This holds the callback to where the data retrieved is sent back. 46 // This holds the callback to where the data retrieved is sent back.
78 content::URLDataSource::GotDataCallback callback_; 47 content::URLDataSource::GotDataCallback callback_;
79 }; 48 };
80 49
81 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( 50 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
82 const content::URLDataSource::GotDataCallback& callback) 51 const content::URLDataSource::GotDataCallback& callback)
83 : callback_(callback) {} 52 : callback_(callback) {
53 }
84 54
85 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {} 55 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
56 }
86 57
87 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady( 58 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady(
88 const DistilledArticleProto* article_proto) { 59 const DistilledArticleProto* article_proto) {
89 DCHECK(article_proto); 60 std::string unsafe_page_html = viewer::GetUnsafeHtml(article_proto);
90 std::string title;
91 std::string unsafe_article_html;
92 if (article_proto->has_title() && article_proto->pages_size() > 0 &&
93 article_proto->pages(0).has_html()) {
94 title = net::EscapeForHTML(article_proto->title());
95 // TODO(shashishekhar): Add support for correcting displaying multiple pages
96 // after discussing the right way to display them.
97 std::ostringstream unsafe_output_stream;
98 for (int page_num = 0; page_num < article_proto->pages_size(); ++page_num) {
99 unsafe_output_stream << article_proto->pages(page_num).html();
100 }
101 unsafe_article_html = unsafe_output_stream.str();
102 } else {
103 title = l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE);
104 unsafe_article_html =
105 l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT);
106 }
107
108 std::string original_url;
109 if (article_proto->pages_size() > 0 && article_proto->pages(0).has_url()) {
110 original_url = article_proto->pages(0).url();
111 }
112
113 std::string unsafe_page_html =
114 ReplaceHtmlTemplateValues(title, unsafe_article_html, original_url);
115 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); 61 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
116 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 62 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
117 } 63 }
118 64
119 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated( 65 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated(
120 ArticleDistillationUpdate article_update) { 66 ArticleDistillationUpdate article_update) {
121 // TODO(nyquist): Add support for displaying pages incrementally. 67 // TODO(nyquist): Add support for displaying pages incrementally.
122 } 68 }
123 69
124 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle( 70 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle(
125 scoped_ptr<ViewerHandle> viewer_handle) { 71 scoped_ptr<ViewerHandle> viewer_handle) {
126 viewer_handle_ = viewer_handle.Pass(); 72 viewer_handle_ = viewer_handle.Pass();
127 } 73 }
128 74
129 DomDistillerViewerSource::DomDistillerViewerSource( 75 DomDistillerViewerSource::DomDistillerViewerSource(
130 DomDistillerServiceInterface* dom_distiller_service, 76 DomDistillerServiceInterface* dom_distiller_service,
131 const std::string& scheme) 77 const std::string& scheme)
132 : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {} 78 : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {
79 }
133 80
134 DomDistillerViewerSource::~DomDistillerViewerSource() {} 81 DomDistillerViewerSource::~DomDistillerViewerSource() {
82 }
135 83
136 std::string DomDistillerViewerSource::GetSource() const { 84 std::string DomDistillerViewerSource::GetSource() const {
137 return scheme_ + "://"; 85 return scheme_ + "://";
138 } 86 }
139 87
140 void DomDistillerViewerSource::StartDataRequest( 88 void DomDistillerViewerSource::StartDataRequest(
141 const std::string& path, 89 const std::string& path,
142 int render_process_id, 90 int render_process_id,
143 int render_frame_id, 91 int render_frame_id,
144 const content::URLDataSource::GotDataCallback& callback) { 92 const content::URLDataSource::GotDataCallback& callback) {
145 content::RenderFrameHost* render_frame_host = 93 content::RenderFrameHost* render_frame_host =
146 content::RenderFrameHost::FromID(render_process_id, render_frame_id); 94 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
147 DCHECK(render_frame_host); 95 DCHECK(render_frame_host);
148 content::RenderViewHost* render_view_host = 96 content::RenderViewHost* render_view_host =
149 render_frame_host->GetRenderViewHost(); 97 render_frame_host->GetRenderViewHost();
150 DCHECK(render_view_host); 98 DCHECK(render_view_host);
151 CHECK_EQ(0, render_view_host->GetEnabledBindings()); 99 CHECK_EQ(0, render_view_host->GetEnabledBindings());
152 100
153 if (kCssPath == path) { 101 if (kCssPath == path) {
154 std::string css = ResourceBundle::GetSharedInstance() 102 std::string css = viewer::GetCss();
155 .GetRawDataResource(IDR_DISTILLER_CSS)
156 .as_string();
157 callback.Run(base::RefCountedString::TakeString(&css)); 103 callback.Run(base::RefCountedString::TakeString(&css));
158 return; 104 return;
159 } 105 }
160 106
161 RequestViewerHandle* request_viewer_handle = 107 RequestViewerHandle* request_viewer_handle =
162 new RequestViewerHandle(callback); 108 new RequestViewerHandle(callback);
163 scoped_ptr<ViewerHandle> viewer_handle = 109 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
164 CreateViewRequest(path, request_viewer_handle); 110 dom_distiller_service_, path, request_viewer_handle);
165 111
166 if (viewer_handle) { 112 if (viewer_handle) {
167 // The service returned a |ViewerHandle| and guarantees it will call 113 // The service returned a |ViewerHandle| and guarantees it will call
168 // the |RequestViewerHandle|, so passing ownership to it, to ensure the 114 // the |RequestViewerHandle|, so passing ownership to it, to ensure the
169 // request is not cancelled. The |RequestViewerHandle| will delete itself 115 // request is not cancelled. The |RequestViewerHandle| will delete itself
170 // after receiving the callback. 116 // after receiving the callback.
171 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); 117 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass());
172 } else { 118 } else {
173 // The service did not return a |ViewerHandle|, which means the 119 // The service did not return a |ViewerHandle|, which means the
174 // |RequestViewerHandle| will never be called, so clean up now. 120 // |RequestViewerHandle| will never be called, so clean up now.
175 delete request_viewer_handle; 121 delete request_viewer_handle;
176 122
177 std::string title = l10n_util::GetStringUTF8( 123 std::string error_page_html = viewer::GetErrorPageHtml();
178 IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE); 124 callback.Run(base::RefCountedString::TakeString(&error_page_html));
179 std::string content = l10n_util::GetStringUTF8(
180 IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT);
181 std::string html = ReplaceHtmlTemplateValues(title, content, "");
182 callback.Run(base::RefCountedString::TakeString(&html));
183 } 125 }
184 }; 126 };
185 127
186 std::string DomDistillerViewerSource::GetMimeType( 128 std::string DomDistillerViewerSource::GetMimeType(
187 const std::string& path) const { 129 const std::string& path) const {
188 if (path == kCssPath) 130 if (path == kCssPath)
189 return "text/css"; 131 return "text/css";
190 return "text/html"; 132 return "text/html";
191 } 133 }
192 134
193 bool DomDistillerViewerSource::ShouldServiceRequest( 135 bool DomDistillerViewerSource::ShouldServiceRequest(
194 const net::URLRequest* request) const { 136 const net::URLRequest* request) const {
195 return request->url().SchemeIs(scheme_.c_str()); 137 return request->url().SchemeIs(scheme_.c_str());
196 } 138 }
197 139
198 // TODO(nyquist): Start tracking requests using this method. 140 // TODO(nyquist): Start tracking requests using this method.
199 void DomDistillerViewerSource::WillServiceRequest( 141 void DomDistillerViewerSource::WillServiceRequest(
200 const net::URLRequest* request, 142 const net::URLRequest* request,
201 std::string* path) const {} 143 std::string* path) const {
144 }
202 145
203 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() 146 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc()
204 const { 147 const {
205 return "object-src 'none'; style-src 'self';"; 148 return "object-src 'none'; style-src 'self';";
206 } 149 }
207 150
208 scoped_ptr<ViewerHandle> DomDistillerViewerSource::CreateViewRequest(
209 const std::string& path,
210 ViewRequestDelegate* view_request_delegate) {
211 std::string entry_id =
212 url_utils::GetValueForKeyInUrlPathQuery(path, kEntryIdKey);
213 bool has_valid_entry_id = !entry_id.empty();
214 entry_id = StringToUpperASCII(entry_id);
215
216 std::string requested_url_str =
217 url_utils::GetValueForKeyInUrlPathQuery(path, kUrlKey);
218 GURL requested_url(requested_url_str);
219 bool has_valid_url = url_utils::IsUrlDistillable(requested_url);
220
221 if (has_valid_entry_id && has_valid_url) {
222 // It is invalid to specify a query param for both |kEntryIdKey| and
223 // |kUrlKey|.
224 return scoped_ptr<ViewerHandle>();
225 }
226
227 if (has_valid_entry_id) {
228 return dom_distiller_service_->ViewEntry(view_request_delegate, entry_id)
229 .Pass();
230 } else if (has_valid_url) {
231 return dom_distiller_service_->ViewUrl(view_request_delegate, requested_url)
232 .Pass();
233 }
234
235 // It is invalid to not specify a query param for |kEntryIdKey| or |kUrlKey|.
236 return scoped_ptr<ViewerHandle>();
237 }
238
239 } // namespace dom_distiller 151 } // namespace dom_distiller
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698