Chromium Code Reviews| Index: components/dom_distiller/content/dom_distiller_viewer_source.cc |
| diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.cc b/components/dom_distiller/content/dom_distiller_viewer_source.cc |
| index e614359ba8de2ce7895d2fa96b237ede8753dc70..efadfcfc2bfeab6db75c30f089fcb51c006c389d 100644 |
| --- a/components/dom_distiller/content/dom_distiller_viewer_source.cc |
| +++ b/components/dom_distiller/content/dom_distiller_viewer_source.cc |
| @@ -5,18 +5,97 @@ |
| #include "components/dom_distiller/content/dom_distiller_viewer_source.h" |
| #include <string> |
| +#include <vector> |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/strings/string_util.h" |
| +#include "components/dom_distiller/core/dom_distiller_service.h" |
| +#include "components/dom_distiller/core/proto/distilled_page.pb.h" |
| +#include "components/dom_distiller/core/task_tracker.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/render_view_host.h" |
| +#include "grit/component_strings.h" |
| +#include "grit/dom_distiller_resources.h" |
| +#include "net/base/escape.h" |
| #include "net/url_request/url_request.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| #include "url/gurl.h" |
| +namespace { |
| + |
| +std::string ReplaceHtmlTemplateValues(std::string title, std::string content) { |
| + base::StringPiece html_template = |
| + ResourceBundle::GetSharedInstance().GetRawDataResource( |
| + IDR_DOM_DISTILLER_VIEWER_HTML); |
| + std::vector<std::string> substitutions; |
| + substitutions.push_back(title); // $1 |
| + substitutions.push_back(title); // $2 |
| + substitutions.push_back(content); // $3 |
| + return ReplaceStringPlaceholders(html_template, substitutions, NULL); |
| +} |
| + |
| +} // namespace |
| + |
| namespace dom_distiller { |
| -DomDistillerViewerSource::DomDistillerViewerSource(const std::string& scheme) |
| - : scheme_(scheme) {} |
| +// Handles receiving data asynchronously for a specific entry, and passing |
| +// it along to the data callback for the data source. |
| +class RequestViewerHandle : public ViewRequestDelegate { |
| + public: |
| + explicit RequestViewerHandle( |
| + const content::URLDataSource::GotDataCallback& callback); |
| + virtual ~RequestViewerHandle(); |
| + |
| + // ViewRequestDelegate implementation. |
| + virtual void OnArticleReady(DistilledPageProto* proto) OVERRIDE; |
| + |
| + void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle); |
| + |
| + private: |
| + // The handle to the view request towards the DomDistillerService. It |
| + // needs to be kept around to ensure the distillation request finishes. |
| + scoped_ptr<ViewerHandle> viewer_handle_; |
| + |
| + // This holds the callback to where the data retreived is sent back. |
|
cjhopman
2014/01/28 02:56:56
s/retreived/retrieved/
nyquist
2014/01/28 18:16:12
Done.
|
| + content::URLDataSource::GotDataCallback callback_; |
| +}; |
| + |
| +RequestViewerHandle::RequestViewerHandle( |
| + const content::URLDataSource::GotDataCallback& callback) |
| + : callback_(callback) {} |
| + |
| +RequestViewerHandle::~RequestViewerHandle() {} |
| + |
| +void RequestViewerHandle::OnArticleReady(DistilledPageProto* proto) { |
| + DCHECK(proto); |
| + std::string title; |
| + std::string unsafe_article_html; |
| + if (proto->has_title() && proto->has_html()) { |
| + title = net::EscapeForHTML(proto->title()); |
| + unsafe_article_html = proto->html(); |
| + } else { |
| + title = l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE); |
| + unsafe_article_html = |
| + l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT); |
| + } |
| + std::string unsafe_page_html = |
| + ReplaceHtmlTemplateValues(title, unsafe_article_html); |
| + callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html)); |
| + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| +} |
| + |
| +void RequestViewerHandle::TakeViewerHandle( |
| + scoped_ptr<ViewerHandle> viewer_handle) { |
| + viewer_handle_ = viewer_handle.Pass(); |
| +} |
| + |
| +DomDistillerViewerSource::DomDistillerViewerSource( |
| + DomDistillerService* dom_distiller_service, const std::string& scheme) |
| + : scheme_(scheme), |
| + dom_distiller_service_(dom_distiller_service) {} |
| DomDistillerViewerSource::~DomDistillerViewerSource() {} |
| @@ -35,13 +114,33 @@ void DomDistillerViewerSource::StartDataRequest( |
| DCHECK(render_view_host); |
| CHECK_EQ(0, render_view_host->GetEnabledBindings()); |
| - std::string page_template = "Aloha!"; |
| - callback.Run(base::RefCountedString::TakeString(&page_template)); |
| + RequestViewerHandle* request_viewer_handle = |
|
cjhopman
2014/01/28 02:56:56
What do you think about making this a scoped_ptr,
nyquist
2014/01/28 18:16:12
Done.
|
| + new RequestViewerHandle(callback); |
| + std::string entry_id = StringToUpperASCII(path); |
| + scoped_ptr<ViewerHandle> viewer_handle = |
| + dom_distiller_service_->ViewEntry(request_viewer_handle, entry_id); |
| + if (viewer_handle) { |
| + // The service returned a |ViewerHandle| and guarantees it will call |
| + // the |RequestViewerHandle|, so passing ownership to it, to ensure the |
| + // request is not cancelled. |
| + request_viewer_handle->TakeViewerHandle(viewer_handle.Pass()); |
| + } else { |
| + // The service did not return a |ViewerHandle|, which means the |
| + // |RequestViewerHandle| will never be called, so clean up now. |
| + delete request_viewer_handle; |
| + |
| + std::string title = l10n_util::GetStringUTF8( |
| + IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE); |
| + std::string content = l10n_util::GetStringUTF8( |
| + IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT); |
| + std::string html = ReplaceHtmlTemplateValues(title, content); |
| + callback.Run(base::RefCountedString::TakeString(&html)); |
| + } |
| }; |
| std::string DomDistillerViewerSource::GetMimeType(const std::string& path) |
| const { |
| - return "text/plain"; |
| + return "text/html"; |
| } |
| bool DomDistillerViewerSource::ShouldServiceRequest( |
| @@ -49,4 +148,12 @@ bool DomDistillerViewerSource::ShouldServiceRequest( |
| return request->url().SchemeIs(scheme_.c_str()); |
| } |
| +void DomDistillerViewerSource::WillServiceRequest( |
| + const net::URLRequest* request, |
| + std::string* path) const { |
| + // Since the full request is not available to StartDataRequest, replace the |
| + // path to contain the data needed. |
| + *path = request->url().host(); |
| +}; |
| + |
| } // namespace dom_distiller |