| 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_service.h" | 18 #include "components/dom_distiller/core/dom_distiller_service.h" |
| 18 #include "components/dom_distiller/core/external_feedback_reporter.h" | 19 #include "components/dom_distiller/core/external_feedback_reporter.h" |
| 19 #include "components/dom_distiller/core/feedback_reporter.h" | 20 #include "components/dom_distiller/core/feedback_reporter.h" |
| 20 #include "components/dom_distiller/core/task_tracker.h" | 21 #include "components/dom_distiller/core/task_tracker.h" |
| 21 #include "components/dom_distiller/core/url_constants.h" | 22 #include "components/dom_distiller/core/url_constants.h" |
| 22 #include "components/dom_distiller/core/viewer.h" | 23 #include "components/dom_distiller/core/viewer.h" |
| 23 #include "content/public/browser/navigation_details.h" | 24 #include "content/public/browser/navigation_details.h" |
| 24 #include "content/public/browser/navigation_entry.h" | 25 #include "content/public/browser/navigation_entry.h" |
| 25 #include "content/public/browser/render_frame_host.h" | 26 #include "content/public/browser/render_frame_host.h" |
| 26 #include "content/public/browser/render_view_host.h" | 27 #include "content/public/browser/render_view_host.h" |
| 27 #include "content/public/browser/user_metrics.h" | 28 #include "content/public/browser/user_metrics.h" |
| 28 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 29 #include "content/public/browser/web_contents_observer.h" | 30 #include "content/public/browser/web_contents_observer.h" |
| 30 #include "net/base/url_util.h" | 31 #include "net/base/url_util.h" |
| 31 #include "net/url_request/url_request.h" | 32 #include "net/url_request/url_request.h" |
| 32 | 33 |
| 33 namespace dom_distiller { | 34 namespace dom_distiller { |
| 34 | 35 |
| 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 |
| 35 // Handles receiving data asynchronously for a specific entry, and passing | 60 // Handles receiving data asynchronously for a specific entry, and passing |
| 36 // it along to the data callback for the data source. Lifetime matches that of | 61 // it along to the data callback for the data source. Lifetime matches that of |
| 37 // the current main frame's page in the Viewer instance. | 62 // the current main frame's page in the Viewer instance. |
| 38 class DomDistillerViewerSource::RequestViewerHandle | 63 class DomDistillerViewerSource::RequestViewerHandle |
| 39 : public ViewRequestDelegate, | 64 : public DomDistillerRequestViewBase, |
| 40 public content::WebContentsObserver, | 65 public content::WebContentsObserver { |
| 41 public DistilledPagePrefs::Observer { | |
| 42 public: | 66 public: |
| 43 explicit RequestViewerHandle( | 67 RequestViewerHandle(content::WebContents* web_contents, |
| 44 content::WebContents* web_contents, | 68 const std::string& expected_scheme, |
| 45 const std::string& expected_scheme, | 69 const std::string& expected_request_path, |
| 46 const std::string& expected_request_path, | 70 scoped_ptr<ContentDataCallback> callback, |
| 47 const content::URLDataSource::GotDataCallback& callback, | 71 DistilledPagePrefs* distilled_page_prefs); |
| 48 DistilledPagePrefs* distilled_page_prefs); | |
| 49 ~RequestViewerHandle() override; | 72 ~RequestViewerHandle() override; |
| 50 | 73 |
| 51 // Flag this request as an error and send the error page template. | |
| 52 void flagAsErrorPage(); | |
| 53 | |
| 54 // ViewRequestDelegate implementation: | |
| 55 void OnArticleReady(const DistilledArticleProto* article_proto) override; | |
| 56 | |
| 57 void OnArticleUpdated(ArticleDistillationUpdate article_update) override; | |
| 58 | |
| 59 void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle); | |
| 60 | |
| 61 // content::WebContentsObserver implementation: | 74 // content::WebContentsObserver implementation: |
| 62 void DidNavigateMainFrame( | 75 void DidNavigateMainFrame( |
| 63 const content::LoadCommittedDetails& details, | 76 const content::LoadCommittedDetails& details, |
| 64 const content::FrameNavigateParams& params) override; | 77 const content::FrameNavigateParams& params) override; |
| 65 void RenderProcessGone(base::TerminationStatus status) override; | 78 void RenderProcessGone(base::TerminationStatus status) override; |
| 66 void WebContentsDestroyed() override; | 79 void WebContentsDestroyed() override; |
| 67 void DidFinishLoad(content::RenderFrameHost* render_frame_host, | 80 void DidFinishLoad(content::RenderFrameHost* render_frame_host, |
| 68 const GURL& validated_url) override; | 81 const GURL& validated_url) override; |
| 69 | 82 |
| 70 private: | 83 private: |
| 71 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't | 84 // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't |
| 72 // ready. | 85 // ready. |
| 73 void SendJavaScript(const std::string& buffer); | 86 void SendJavaScript(const std::string& buffer) override; |
| 74 | 87 |
| 75 // Cancels the current view request. Once called, no updates will be | 88 // Cancels the current view request. Once called, no updates will be |
| 76 // propagated to the view, and the request to DomDistillerService will be | 89 // propagated to the view, and the request to DomDistillerService will be |
| 77 // cancelled. | 90 // cancelled. |
| 78 void Cancel(); | 91 void Cancel(); |
| 79 | 92 |
| 80 // DistilledPagePrefs::Observer implementation: | |
| 81 void OnChangeFontFamily( | |
| 82 DistilledPagePrefs::FontFamily new_font_family) override; | |
| 83 void OnChangeTheme(DistilledPagePrefs::Theme new_theme) override; | |
| 84 | |
| 85 // The handle to the view request towards the DomDistillerService. It | |
| 86 // needs to be kept around to ensure the distillation request finishes. | |
| 87 scoped_ptr<ViewerHandle> viewer_handle_; | |
| 88 | |
| 89 // The scheme hosting the current view request; | 93 // The scheme hosting the current view request; |
| 90 std::string expected_scheme_; | 94 std::string expected_scheme_; |
| 91 | 95 |
| 92 // The query path for the current view request. | 96 // The query path for the current view request. |
| 93 std::string expected_request_path_; | 97 std::string expected_request_path_; |
| 94 | 98 |
| 95 // Holds the callback to where the data retrieved is sent back. | |
| 96 content::URLDataSource::GotDataCallback callback_; | |
| 97 | |
| 98 // Number of pages of the distilled article content that have been rendered by | |
| 99 // the viewer. | |
| 100 int page_count_; | |
| 101 | |
| 102 // Interface for accessing preferences for distilled pages. | |
| 103 DistilledPagePrefs* distilled_page_prefs_; | |
| 104 | |
| 105 // Whether the page is sufficiently initialized to handle updates from the | 99 // Whether the page is sufficiently initialized to handle updates from the |
| 106 // distiller. | 100 // distiller. |
| 107 bool waiting_for_page_ready_; | 101 bool waiting_for_page_ready_; |
| 108 | 102 |
| 109 // Temporary store of pending JavaScript if the page isn't ready to receive | 103 // Temporary store of pending JavaScript if the page isn't ready to receive |
| 110 // data from distillation. | 104 // data from distillation. |
| 111 std::string buffer_; | 105 std::string buffer_; |
| 112 | |
| 113 // Flag to tell this observer that the web contents are in an error state. | |
| 114 bool is_error_page_; | |
| 115 }; | 106 }; |
| 116 | 107 |
| 117 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( | 108 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( |
| 118 content::WebContents* web_contents, | 109 content::WebContents* web_contents, |
| 119 const std::string& expected_scheme, | 110 const std::string& expected_scheme, |
| 120 const std::string& expected_request_path, | 111 const std::string& expected_request_path, |
| 121 const content::URLDataSource::GotDataCallback& callback, | 112 scoped_ptr<ContentDataCallback> callback, |
| 122 DistilledPagePrefs* distilled_page_prefs) | 113 DistilledPagePrefs* distilled_page_prefs) |
| 123 : expected_scheme_(expected_scheme), | 114 : DomDistillerRequestViewBase(callback.Pass(), distilled_page_prefs), |
| 115 expected_scheme_(expected_scheme), |
| 124 expected_request_path_(expected_request_path), | 116 expected_request_path_(expected_request_path), |
| 125 callback_(callback), | 117 waiting_for_page_ready_(true) { |
| 126 page_count_(0), | |
| 127 distilled_page_prefs_(distilled_page_prefs), | |
| 128 waiting_for_page_ready_(true), | |
| 129 is_error_page_(false) { | |
| 130 content::WebContentsObserver::Observe(web_contents); | 118 content::WebContentsObserver::Observe(web_contents); |
| 131 distilled_page_prefs_->AddObserver(this); | 119 distilled_page_prefs_->AddObserver(this); |
| 132 } | 120 } |
| 133 | 121 |
| 134 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { | 122 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { |
| 135 distilled_page_prefs_->RemoveObserver(this); | 123 distilled_page_prefs_->RemoveObserver(this); |
| 136 } | 124 } |
| 137 | 125 |
| 138 void DomDistillerViewerSource::RequestViewerHandle::flagAsErrorPage() { | |
| 139 is_error_page_ = true; | |
| 140 std::string error_page_html = viewer::GetErrorPageHtml( | |
| 141 distilled_page_prefs_->GetTheme(), | |
| 142 distilled_page_prefs_->GetFontFamily()); | |
| 143 callback_.Run(base::RefCountedString::TakeString(&error_page_html)); | |
| 144 } | |
| 145 | |
| 146 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript( | 126 void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript( |
| 147 const std::string& buffer) { | 127 const std::string& buffer) { |
| 148 if (waiting_for_page_ready_) { | 128 if (waiting_for_page_ready_) { |
| 149 buffer_ += buffer; | 129 buffer_ += buffer; |
| 150 } else { | 130 } else { |
| 151 if (web_contents()) { | 131 if (web_contents()) { |
| 152 web_contents()->GetMainFrame()->ExecuteJavaScript( | 132 web_contents()->GetMainFrame()->ExecuteJavaScript( |
| 153 base::UTF8ToUTF16(buffer)); | 133 base::UTF8ToUTF16(buffer)); |
| 154 } | 134 } |
| 155 } | 135 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 183 content::WebContentsObserver::Observe(NULL); | 163 content::WebContentsObserver::Observe(NULL); |
| 184 | 164 |
| 185 // Schedule the Viewer for deletion. Ensures distillation is cancelled, and | 165 // Schedule the Viewer for deletion. Ensures distillation is cancelled, and |
| 186 // any pending data stored in |buffer_| is released. | 166 // any pending data stored in |buffer_| is released. |
| 187 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 167 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 188 } | 168 } |
| 189 | 169 |
| 190 void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad( | 170 void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad( |
| 191 content::RenderFrameHost* render_frame_host, | 171 content::RenderFrameHost* render_frame_host, |
| 192 const GURL& validated_url) { | 172 const GURL& validated_url) { |
| 193 if (is_error_page_) { | 173 if (IsErrorPage()) { |
| 194 waiting_for_page_ready_ = false; | 174 waiting_for_page_ready_ = false; |
| 195 SendJavaScript(viewer::GetErrorPageJs()); | 175 SendJavaScript(viewer::GetErrorPageJs()); |
| 196 SendJavaScript(viewer::GetShowFeedbackFormJs()); | 176 SendJavaScript(viewer::GetShowFeedbackFormJs()); |
| 197 Cancel(); // This will cause the object to clean itself up. | 177 Cancel(); // This will cause the object to clean itself up. |
| 198 return; | 178 return; |
| 199 } | 179 } |
| 200 | 180 |
| 201 if (render_frame_host->GetParent()) { | 181 if (render_frame_host->GetParent()) { |
| 202 return; | 182 return; |
| 203 } | 183 } |
| 204 waiting_for_page_ready_ = false; | 184 waiting_for_page_ready_ = false; |
| 205 if (buffer_.empty()) { | 185 if (buffer_.empty()) { |
| 206 return; | 186 return; |
| 207 } | 187 } |
| 208 web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(buffer_)); | 188 web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(buffer_)); |
| 209 buffer_.clear(); | 189 buffer_.clear(); |
| 210 } | 190 } |
| 211 | 191 |
| 212 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady( | |
| 213 const DistilledArticleProto* article_proto) { | |
| 214 // TODO(mdjones): Move this logic to super class so it can be used in both | |
| 215 // android and IOS. http://crbug.com/472797 | |
| 216 if (page_count_ == 0) { | |
| 217 std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml( | |
| 218 &article_proto->pages(0), | |
| 219 distilled_page_prefs_->GetTheme(), | |
| 220 distilled_page_prefs_->GetFontFamily()); | |
| 221 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); | |
| 222 // Send first page to client. | |
| 223 SendJavaScript(viewer::GetUnsafeArticleContentJs(article_proto)); | |
| 224 // If any content was loaded, show the feedback form. | |
| 225 SendJavaScript(viewer::GetShowFeedbackFormJs()); | |
| 226 } else if (page_count_ == article_proto->pages_size()) { | |
| 227 // We may still be showing the "Loading" indicator. | |
| 228 SendJavaScript(viewer::GetToggleLoadingIndicatorJs(true)); | |
| 229 } else { | |
| 230 // It's possible that we didn't get some incremental updates from the | |
| 231 // distiller. Ensure all remaining pages are flushed to the viewer. | |
| 232 for (;page_count_ < article_proto->pages_size(); page_count_++) { | |
| 233 const DistilledPageProto& page = article_proto->pages(page_count_); | |
| 234 SendJavaScript( | |
| 235 viewer::GetUnsafeIncrementalDistilledPageJs( | |
| 236 &page, | |
| 237 page_count_ == article_proto->pages_size())); | |
| 238 } | |
| 239 } | |
| 240 // No need to hold on to the ViewerHandle now that distillation is complete. | |
| 241 viewer_handle_.reset(); | |
| 242 } | |
| 243 | |
| 244 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated( | |
| 245 ArticleDistillationUpdate article_update) { | |
| 246 for (;page_count_ < static_cast<int>(article_update.GetPagesSize()); | |
| 247 page_count_++) { | |
| 248 const DistilledPageProto& page = | |
| 249 article_update.GetDistilledPage(page_count_); | |
| 250 // Send the page content to the client. This will execute after the page is | |
| 251 // ready. | |
| 252 SendJavaScript(viewer::GetUnsafeIncrementalDistilledPageJs(&page, false)); | |
| 253 | |
| 254 if (page_count_ == 0) { | |
| 255 // This is the first page, so send Viewer page scaffolding too. | |
| 256 std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml( | |
| 257 &page, | |
| 258 distilled_page_prefs_->GetTheme(), | |
| 259 distilled_page_prefs_->GetFontFamily()); | |
| 260 callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); | |
| 261 // If any content was loaded, show the feedback form. | |
| 262 SendJavaScript(viewer::GetShowFeedbackFormJs()); | |
| 263 } | |
| 264 } | |
| 265 } | |
| 266 | |
| 267 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle( | |
| 268 scoped_ptr<ViewerHandle> viewer_handle) { | |
| 269 viewer_handle_ = viewer_handle.Pass(); | |
| 270 } | |
| 271 | |
| 272 void DomDistillerViewerSource::RequestViewerHandle::OnChangeTheme( | |
| 273 DistilledPagePrefs::Theme new_theme) { | |
| 274 SendJavaScript(viewer::GetDistilledPageThemeJs(new_theme)); | |
| 275 } | |
| 276 | |
| 277 void DomDistillerViewerSource::RequestViewerHandle::OnChangeFontFamily( | |
| 278 DistilledPagePrefs::FontFamily new_font) { | |
| 279 SendJavaScript(viewer::GetDistilledPageFontFamilyJs(new_font)); | |
| 280 } | |
| 281 | |
| 282 DomDistillerViewerSource::DomDistillerViewerSource( | 192 DomDistillerViewerSource::DomDistillerViewerSource( |
| 283 DomDistillerServiceInterface* dom_distiller_service, | 193 DomDistillerServiceInterface* dom_distiller_service, |
| 284 const std::string& scheme, | 194 const std::string& scheme, |
| 285 scoped_ptr<ExternalFeedbackReporter> external_reporter) | 195 scoped_ptr<ExternalFeedbackReporter> external_reporter) |
| 286 : scheme_(scheme), | 196 : scheme_(scheme), |
| 287 dom_distiller_service_(dom_distiller_service), | 197 dom_distiller_service_(dom_distiller_service), |
| 288 external_feedback_reporter_(external_reporter.Pass()) { | 198 external_feedback_reporter_(external_reporter.Pass()) { |
| 289 } | 199 } |
| 290 | 200 |
| 291 DomDistillerViewerSource::~DomDistillerViewerSource() { | 201 DomDistillerViewerSource::~DomDistillerViewerSource() { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 return; | 241 return; |
| 332 } else if (kFeedbackGood == path) { | 242 } else if (kFeedbackGood == path) { |
| 333 FeedbackReporter::ReportQuality(true); | 243 FeedbackReporter::ReportQuality(true); |
| 334 return; | 244 return; |
| 335 } | 245 } |
| 336 content::WebContents* web_contents = | 246 content::WebContents* web_contents = |
| 337 content::WebContents::FromRenderFrameHost(render_frame_host); | 247 content::WebContents::FromRenderFrameHost(render_frame_host); |
| 338 DCHECK(web_contents); | 248 DCHECK(web_contents); |
| 339 // An empty |path| is invalid, but guard against it. If not empty, assume | 249 // An empty |path| is invalid, but guard against it. If not empty, assume |
| 340 // |path| starts with '?', which is stripped away. | 250 // |path| starts with '?', which is stripped away. |
| 251 scoped_ptr<ContentDataCallback> data_callback( |
| 252 new ContentDataCallback(callback)); |
| 341 const std::string path_after_query_separator = | 253 const std::string path_after_query_separator = |
| 342 path.size() > 0 ? path.substr(1) : ""; | 254 path.size() > 0 ? path.substr(1) : ""; |
| 343 RequestViewerHandle* request_viewer_handle = new RequestViewerHandle( | 255 RequestViewerHandle* request_viewer_handle = new RequestViewerHandle( |
| 344 web_contents, scheme_, path_after_query_separator, callback, | 256 web_contents, scheme_, path_after_query_separator, data_callback.Pass(), |
| 345 dom_distiller_service_->GetDistilledPagePrefs()); | 257 dom_distiller_service_->GetDistilledPagePrefs()); |
| 346 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( | 258 scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( |
| 347 dom_distiller_service_, path, request_viewer_handle, | 259 dom_distiller_service_, path, request_viewer_handle, |
| 348 web_contents->GetContainerBounds().size()); | 260 web_contents->GetContainerBounds().size()); |
| 349 | 261 |
| 350 if (viewer_handle) { | 262 if (viewer_handle) { |
| 351 // The service returned a |ViewerHandle| and guarantees it will call | 263 // The service returned a |ViewerHandle| and guarantees it will call |
| 352 // the |RequestViewerHandle|, so passing ownership to it, to ensure the | 264 // the |RequestViewerHandle|, so passing ownership to it, to ensure the |
| 353 // request is not cancelled. The |RequestViewerHandle| will delete itself | 265 // request is not cancelled. The |RequestViewerHandle| will delete itself |
| 354 // after receiving the callback. | 266 // after receiving the callback. |
| 355 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); | 267 request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); |
| 356 } else { | 268 } else { |
| 357 request_viewer_handle->flagAsErrorPage(); | 269 request_viewer_handle->FlagAsErrorPage(); |
| 358 } | 270 } |
| 359 }; | 271 }; |
| 360 | 272 |
| 361 std::string DomDistillerViewerSource::GetMimeType( | 273 std::string DomDistillerViewerSource::GetMimeType( |
| 362 const std::string& path) const { | 274 const std::string& path) const { |
| 363 if (kViewerCssPath == path) { | 275 if (kViewerCssPath == path) { |
| 364 return "text/css"; | 276 return "text/css"; |
| 365 } | 277 } |
| 366 if (kViewerJsPath == path) { | 278 if (kViewerJsPath == path) { |
| 367 return "text/javascript"; | 279 return "text/javascript"; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 383 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() | 295 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc() |
| 384 const { | 296 const { |
| 385 return "object-src 'none'; style-src 'self' https://fonts.googleapis.com;"; | 297 return "object-src 'none'; style-src 'self' https://fonts.googleapis.com;"; |
| 386 } | 298 } |
| 387 | 299 |
| 388 std::string DomDistillerViewerSource::GetContentSecurityPolicyFrameSrc() const { | 300 std::string DomDistillerViewerSource::GetContentSecurityPolicyFrameSrc() const { |
| 389 return "frame-src *;"; | 301 return "frame-src *;"; |
| 390 } | 302 } |
| 391 | 303 |
| 392 } // namespace dom_distiller | 304 } // namespace dom_distiller |
| OLD | NEW |