diff options
author | nyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 06:20:26 +0000 |
---|---|---|
committer | nyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 06:20:26 +0000 |
commit | 92c4fcddfd6f991c274baf9569712690d91f9100 (patch) | |
tree | 37d58f718b04cc00890f06f42865779f2c2ae4be /components/dom_distiller | |
parent | 572369a3149b5661c342706aa99b896585e21fcf (diff) | |
download | chromium_src-92c4fcddfd6f991c274baf9569712690d91f9100.zip chromium_src-92c4fcddfd6f991c274baf9569712690d91f9100.tar.gz chromium_src-92c4fcddfd6f991c274baf9569712690d91f9100.tar.bz2 |
Add support for displaying distilled articles.
Adds support in the content::URLDataSource for DOM Distiller for displaying
distilled articles.
Also adds preliminary error handling.
Depends on https://codereview.chromium.org/105723002/
BUG=319881
Review URL: https://codereview.chromium.org/134873008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247645 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/dom_distiller')
4 files changed, 152 insertions, 10 deletions
diff --git a/components/dom_distiller/content/DEPS b/components/dom_distiller/content/DEPS index 6be787a..09d00ad 100644 --- a/components/dom_distiller/content/DEPS +++ b/components/dom_distiller/content/DEPS @@ -3,5 +3,7 @@ include_rules = [ "+content/public", "+content/shell", "+content/test", + "+net/base", "+net/test", + "+ui/base/l10n", ] diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.cc b/components/dom_distiller/content/dom_distiller_viewer_source.cc index e614359..c9fa6df 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 retrieved is sent back. + 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,34 @@ 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 = + 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. The |RequestViewerHandle| will delete itself + // after receiving the callback. + 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 +149,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 diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.h b/components/dom_distiller/content/dom_distiller_viewer_source.h index ff08c4e..e2b168a 100644 --- a/components/dom_distiller/content/dom_distiller_viewer_source.h +++ b/components/dom_distiller/content/dom_distiller_viewer_source.h @@ -11,14 +11,16 @@ namespace dom_distiller { +class DomDistillerService; + // Serves HTML and resources for viewing distilled articles. class DomDistillerViewerSource : public content::URLDataSource { public: - DomDistillerViewerSource(const std::string& scheme); - - private: + DomDistillerViewerSource(DomDistillerService* dom_distiller_service, + const std::string& scheme); virtual ~DomDistillerViewerSource(); + private: // Overridden from content::URLDataSource: virtual std::string GetSource() const OVERRIDE; virtual void StartDataRequest( @@ -27,12 +29,18 @@ class DomDistillerViewerSource : public content::URLDataSource { int render_frame_id, const content::URLDataSource::GotDataCallback& callback) OVERRIDE; virtual std::string GetMimeType(const std::string& path) const OVERRIDE; - virtual bool ShouldServiceRequest( - const net::URLRequest* request) const OVERRIDE; + virtual bool ShouldServiceRequest(const net::URLRequest* request) + const OVERRIDE; + virtual void WillServiceRequest(const net::URLRequest* request, + std::string* path) const OVERRIDE; // The scheme this URLDataSource is hosted under. std::string scheme_; + // The service which contains all the functionality needed to interact with + // the list of articles. + DomDistillerService* dom_distiller_service_; + DISALLOW_COPY_AND_ASSIGN(DomDistillerViewerSource); }; diff --git a/components/dom_distiller/content/resources/dom_distiller_viewer.html b/components/dom_distiller/content/resources/dom_distiller_viewer.html new file mode 100644 index 0000000..996cabd6 --- /dev/null +++ b/components/dom_distiller/content/resources/dom_distiller_viewer.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<!-- +Copyright 2014 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> + <meta charset="utf-8"> + <title>$1</title> +</head> +<body> + <div id="mainContent"> + <div id="article"> + <article> + <header> + <h1>$2</h1> + </header> + <div id="content">$3</div> + </article> + </div> + </div> +</body> +</html> |