| OLD | NEW |
| 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/metrics/user_metrics.h" | 14 #include "base/metrics/user_metrics.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "components/dom_distiller/core/distilled_page_prefs.h" | 16 #include "components/dom_distiller/core/distilled_page_prefs.h" |
| 17 #include "components/dom_distiller/core/dom_distiller_request_view_base.h" | 17 #include "components/dom_distiller/core/dom_distiller_request_view_base.h" |
| 18 #include "components/dom_distiller/core/dom_distiller_service.h" | 18 #include "components/dom_distiller/core/dom_distiller_service.h" |
| 19 #include "components/dom_distiller/core/external_feedback_reporter.h" | 19 #include "components/dom_distiller/core/external_feedback_reporter.h" |
| 20 #include "components/dom_distiller/core/feedback_reporter.h" | 20 #include "components/dom_distiller/core/feedback_reporter.h" |
| 21 #include "components/dom_distiller/core/task_tracker.h" | 21 #include "components/dom_distiller/core/task_tracker.h" |
| 22 #include "components/dom_distiller/core/url_constants.h" | 22 #include "components/dom_distiller/core/url_constants.h" |
| 23 #include "components/dom_distiller/core/url_utils.h" |
| 23 #include "components/dom_distiller/core/viewer.h" | 24 #include "components/dom_distiller/core/viewer.h" |
| 24 #include "content/public/browser/navigation_details.h" | 25 #include "content/public/browser/navigation_details.h" |
| 25 #include "content/public/browser/navigation_entry.h" | 26 #include "content/public/browser/navigation_entry.h" |
| 26 #include "content/public/browser/render_frame_host.h" | 27 #include "content/public/browser/render_frame_host.h" |
| 27 #include "content/public/browser/render_view_host.h" | 28 #include "content/public/browser/render_view_host.h" |
| 28 #include "content/public/browser/user_metrics.h" | 29 #include "content/public/browser/user_metrics.h" |
| 29 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
| 30 #include "content/public/browser/web_contents_observer.h" | 31 #include "content/public/browser/web_contents_observer.h" |
| 32 #include "grit/components_strings.h" |
| 31 #include "net/base/url_util.h" | 33 #include "net/base/url_util.h" |
| 32 #include "net/url_request/url_request.h" | 34 #include "net/url_request/url_request.h" |
| 35 #include "ui/base/l10n/l10n_util.h" |
| 33 | 36 |
| 34 namespace dom_distiller { | 37 namespace dom_distiller { |
| 35 | 38 |
| 36 namespace { | |
| 37 | |
| 38 class ContentDataCallback : public DistillerDataCallback { | |
| 39 public: | |
| 40 ContentDataCallback(const content::URLDataSource::GotDataCallback& callback); | |
| 41 // Runs the callback. | |
| 42 void RunCallback(std::string& data) override; | |
| 43 | |
| 44 private: | |
| 45 // The callback that actually gets run. | |
| 46 content::URLDataSource::GotDataCallback callback_; | |
| 47 }; | |
| 48 | |
| 49 ContentDataCallback::ContentDataCallback( | |
| 50 const content::URLDataSource::GotDataCallback& callback) { | |
| 51 callback_ = callback; | |
| 52 } | |
| 53 | |
| 54 void ContentDataCallback::RunCallback(std::string& data) { | |
| 55 callback_.Run(base::RefCountedString::TakeString(&data)); | |
| 56 } | |
| 57 | |
| 58 } // namespace | |
| 59 | |
| 60 // Handles receiving data asynchronously for a specific entry, and passing | 39 // Handles receiving data asynchronously for a specific entry, and passing |
| 61 // it along to the data callback for the data source. Lifetime matches that of | 40 // it along to the data callback for the data source. Lifetime matches that of |
| 62 // the current main frame's page in the Viewer instance. | 41 // the current main frame's page in the Viewer instance. |
| 63 class DomDistillerViewerSource::RequestViewerHandle | 42 class DomDistillerViewerSource::RequestViewerHandle |
| 64 : public DomDistillerRequestViewBase, | 43 : public DomDistillerRequestViewBase, |
| 65 public content::WebContentsObserver { | 44 public content::WebContentsObserver { |
| 66 public: | 45 public: |
| 67 RequestViewerHandle(content::WebContents* web_contents, | 46 RequestViewerHandle(content::WebContents* web_contents, |
| 68 const std::string& expected_scheme, | 47 const std::string& expected_scheme, |
| 69 const std::string& expected_request_path, | 48 const std::string& expected_request_path, |
| 70 scoped_ptr<ContentDataCallback> callback, | |
| 71 DistilledPagePrefs* distilled_page_prefs); | 49 DistilledPagePrefs* distilled_page_prefs); |
| 72 ~RequestViewerHandle() override; | 50 ~RequestViewerHandle() override; |
| 73 | 51 |
| 74 // content::WebContentsObserver implementation: | 52 // content::WebContentsObserver implementation: |
| 75 void DidNavigateMainFrame( | 53 void DidNavigateMainFrame( |
| 76 const content::LoadCommittedDetails& details, | 54 const content::LoadCommittedDetails& details, |
| 77 const content::FrameNavigateParams& params) override; | 55 const content::FrameNavigateParams& params) override; |
| 78 void RenderProcessGone(base::TerminationStatus status) override; | 56 void RenderProcessGone(base::TerminationStatus status) override; |
| 79 void WebContentsDestroyed() override; | 57 void WebContentsDestroyed() override; |
| 80 void DidFinishLoad(content::RenderFrameHost* render_frame_host, | 58 void DidFinishLoad(content::RenderFrameHost* render_frame_host, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 102 | 80 |
| 103 // Temporary store of pending JavaScript if the page isn't ready to receive | 81 // Temporary store of pending JavaScript if the page isn't ready to receive |
| 104 // data from distillation. | 82 // data from distillation. |
| 105 std::string buffer_; | 83 std::string buffer_; |
| 106 }; | 84 }; |
| 107 | 85 |
| 108 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( | 86 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( |
| 109 content::WebContents* web_contents, | 87 content::WebContents* web_contents, |
| 110 const std::string& expected_scheme, | 88 const std::string& expected_scheme, |
| 111 const std::string& expected_request_path, | 89 const std::string& expected_request_path, |
| 112 scoped_ptr<ContentDataCallback> callback, | |
| 113 DistilledPagePrefs* distilled_page_prefs) | 90 DistilledPagePrefs* distilled_page_prefs) |
| 114 : DomDistillerRequestViewBase(callback.Pass(), distilled_page_prefs), | 91 : DomDistillerRequestViewBase(distilled_page_prefs), |
| 115 expected_scheme_(expected_scheme), | 92 expected_scheme_(expected_scheme), |
| 116 expected_request_path_(expected_request_path), | 93 expected_request_path_(expected_request_path), |
| 117 waiting_for_page_ready_(true) { | 94 waiting_for_page_ready_(true) { |
| 118 content::WebContentsObserver::Observe(web_contents); | 95 content::WebContentsObserver::Observe(web_contents); |
| 119 distilled_page_prefs_->AddObserver(this); | 96 distilled_page_prefs_->AddObserver(this); |
| 120 } | 97 } |
| 121 | 98 |
| 122 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { | 99 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { |
| 123 distilled_page_prefs_->RemoveObserver(this); | 100 distilled_page_prefs_->RemoveObserver(this); |
| 124 } | 101 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 // any pending data stored in |buffer_| is released. | 143 // any pending data stored in |buffer_| is released. |
| 167 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 144 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 168 } | 145 } |
| 169 | 146 |
| 170 void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad( | 147 void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad( |
| 171 content::RenderFrameHost* render_frame_host, | 148 content::RenderFrameHost* render_frame_host, |
| 172 const GURL& validated_url) { | 149 const GURL& validated_url) { |
| 173 if (IsErrorPage()) { | 150 if (IsErrorPage()) { |
| 174 waiting_for_page_ready_ = false; | 151 waiting_for_page_ready_ = false; |
| 175 SendJavaScript(viewer::GetErrorPageJs()); | 152 SendJavaScript(viewer::GetErrorPageJs()); |
| 153 std::string title(l10n_util::GetStringUTF8( |
| 154 IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT)); |
| 155 SendJavaScript(viewer::GetSetTitleJs(title)); |
| 156 SendJavaScript(viewer::GetSetTextDirectionJs(std::string("auto"))); |
| 176 SendJavaScript(viewer::GetShowFeedbackFormJs()); | 157 SendJavaScript(viewer::GetShowFeedbackFormJs()); |
| 158 |
| 177 Cancel(); // This will cause the object to clean itself up. | 159 Cancel(); // This will cause the object to clean itself up. |
| 178 return; | 160 return; |
| 179 } | 161 } |
| 180 | 162 |
| 181 if (render_frame_host->GetParent()) { | 163 if (render_frame_host->GetParent()) { |
| 182 return; | 164 return; |
| 183 } | 165 } |
| 184 waiting_for_page_ready_ = false; | 166 waiting_for_page_ready_ = false; |
| 185 if (buffer_.empty()) { | 167 if (buffer_.empty()) { |
| 186 return; | 168 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 } else if (kFeedbackGood == path) { | 225 } else if (kFeedbackGood == path) { |
| 244 FeedbackReporter::ReportQuality(true); | 226 FeedbackReporter::ReportQuality(true); |
| 245 callback.Run(NULL); | 227 callback.Run(NULL); |
| 246 return; | 228 return; |
| 247 } | 229 } |
| 248 content::WebContents* web_contents = | 230 content::WebContents* web_contents = |
| 249 content::WebContents::FromRenderFrameHost(render_frame_host); | 231 content::WebContents::FromRenderFrameHost(render_frame_host); |
| 250 DCHECK(web_contents); | 232 DCHECK(web_contents); |
| 251 // An empty |path| is invalid, but guard against it. If not empty, assume | 233 // An empty |path| is invalid, but guard against it. If not empty, assume |
| 252 // |path| starts with '?', which is stripped away. | 234 // |path| starts with '?', which is stripped away. |
| 253 scoped_ptr<ContentDataCallback> data_callback( | |
| 254 new ContentDataCallback(callback)); | |
| 255 const std::string path_after_query_separator = | 235 const std::string path_after_query_separator = |
| 256 path.size() > 0 ? path.substr(1) : ""; | 236 path.size() > 0 ? path.substr(1) : ""; |
| 257 RequestViewerHandle* request_viewer_handle = new RequestViewerHandle( | 237 RequestViewerHandle* request_viewer_handle = |
| 258 web_contents, scheme_, path_after_query_separator, data_callback.Pass(), | 238 new RequestViewerHandle(web_contents, scheme_, path_after_query_separator, |
| 259 dom_distiller_service_->GetDistilledPagePrefs()); | 239 dom_distiller_service_->GetDistilledPagePrefs()); |
| 260 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( | 240 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( |
| 261 dom_distiller_service_, path, request_viewer_handle, | 241 dom_distiller_service_, path, request_viewer_handle, |
| 262 web_contents->GetContainerBounds().size()); | 242 web_contents->GetContainerBounds().size()); |
| 263 | 243 |
| 244 GURL current_url = web_contents->GetLastCommittedURL(); |
| 245 std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml( |
| 246 url_utils::GetOriginalUrlFromDistillerUrl(current_url).spec(), |
| 247 dom_distiller_service_->GetDistilledPagePrefs()->GetTheme(), |
| 248 dom_distiller_service_->GetDistilledPagePrefs()->GetFontFamily()); |
| 249 |
| 264 if (viewer_handle) { | 250 if (viewer_handle) { |
| 265 // The service returned a |ViewerHandle| and guarantees it will call | 251 // The service returned a |ViewerHandle| and guarantees it will call |
| 266 // the |RequestViewerHandle|, so passing ownership to it, to ensure the | 252 // the |RequestViewerHandle|, so passing ownership to it, to ensure the |
| 267 // request is not cancelled. The |RequestViewerHandle| will delete itself | 253 // request is not cancelled. The |RequestViewerHandle| will delete itself |
| 268 // after receiving the callback. | 254 // after receiving the callback. |
| 269 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); | 255 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); |
| 270 } else { | 256 } else { |
| 271 request_viewer_handle->FlagAsErrorPage(); | 257 request_viewer_handle->FlagAsErrorPage(); |
| 272 } | 258 } |
| 259 |
| 260 // Place template on the page. |
| 261 callback.Run(base::RefCountedString::TakeString(&unsafe_page_html)); |
| 273 }; | 262 }; |
| 274 | 263 |
| 275 std::string DomDistillerViewerSource::GetMimeType( | 264 std::string DomDistillerViewerSource::GetMimeType( |
| 276 const std::string& path) const { | 265 const std::string& path) const { |
| 277 if (kViewerCssPath == path) { | 266 if (kViewerCssPath == path) { |
| 278 return "text/css"; | 267 return "text/css"; |
| 279 } | 268 } |
| 280 if (kViewerJsPath == path) { | 269 if (kViewerJsPath == path) { |
| 281 return "text/javascript"; | 270 return "text/javascript"; |
| 282 } | 271 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 297 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() | 286 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() |
| 298 const { | 287 const { |
| 299 return "object-src 'none'; style-src 'self' https://fonts.googleapis.com;"; | 288 return "object-src 'none'; style-src 'self' https://fonts.googleapis.com;"; |
| 300 } | 289 } |
| 301 | 290 |
| 302 std::string DomDistillerViewerSource::GetContentSecurityPolicyFrameSrc() const { | 291 std::string DomDistillerViewerSource::GetContentSecurityPolicyFrameSrc() const { |
| 303 return "frame-src *;"; | 292 return "frame-src *;"; |
| 304 } | 293 } |
| 305 | 294 |
| 306 } // namespace dom_distiller | 295 } // namespace dom_distiller |
| OLD | NEW |