summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authornyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 06:20:26 +0000
committernyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 06:20:26 +0000
commit92c4fcddfd6f991c274baf9569712690d91f9100 (patch)
tree37d58f718b04cc00890f06f42865779f2c2ae4be /components
parent572369a3149b5661c342706aa99b896585e21fcf (diff)
downloadchromium_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')
-rw-r--r--components/dom_distiller.gypi3
-rw-r--r--components/dom_distiller/content/DEPS2
-rw-r--r--components/dom_distiller/content/dom_distiller_viewer_source.cc118
-rw-r--r--components/dom_distiller/content/dom_distiller_viewer_source.h18
-rw-r--r--components/dom_distiller/content/resources/dom_distiller_viewer.html24
-rw-r--r--components/dom_distiller_resources.grd1
-rw-r--r--components/dom_distiller_strings.grdp12
7 files changed, 168 insertions, 10 deletions
diff --git a/components/dom_distiller.gypi b/components/dom_distiller.gypi
index bec15b7..8cb8901 100644
--- a/components/dom_distiller.gypi
+++ b/components/dom_distiller.gypi
@@ -128,7 +128,10 @@
'target_name': 'dom_distiller_content',
'type': 'static_library',
'dependencies': [
+ 'component_strings.gyp:component_strings',
'dom_distiller_core',
+ 'dom_distiller_resources',
+ '../net/net.gyp:net',
'../skia/skia.gyp:skia',
'../sync/sync.gyp:sync',
],
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>
diff --git a/components/dom_distiller_resources.grd b/components/dom_distiller_resources.grd
index 1faf5d5..b405ae5 100644
--- a/components/dom_distiller_resources.grd
+++ b/components/dom_distiller_resources.grd
@@ -12,6 +12,7 @@
<include name="IDR_ABOUT_DOM_DISTILLER_HTML" file="dom_distiller/webui/resources/about_dom_distiller.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_ABOUT_DOM_DISTILLER_CSS" file="dom_distiller/webui/resources/about_dom_distiller.css" type="BINDATA" />
<include name="IDR_ABOUT_DOM_DISTILLER_JS" file="dom_distiller/webui/resources/about_dom_distiller.js" type="BINDATA" />
+ <include name="IDR_DOM_DISTILLER_VIEWER_HTML" file="dom_distiller/content/resources/dom_distiller_viewer.html" type="BINDATA" />
<include name="IDR_DISTILLER_JS" file="../third_party/readability/js/readability.js" type="BINDATA" />
</includes>
</release>
diff --git a/components/dom_distiller_strings.grdp b/components/dom_distiller_strings.grdp
index 3c9dca7..611237c 100644
--- a/components/dom_distiller_strings.grdp
+++ b/components/dom_distiller_strings.grdp
@@ -22,5 +22,17 @@
<message name="IDS_DOM_DISTILLER_WEBUI_FETCHING_ENTRIES" desc="The text to show while fetching the list of entries on the DOM Distiller debug page.">
Fetching entries...
</message>
+ <message name="IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE" desc="The text to show in place of a reading list article title if the article is not found.">
+ Failed to find article.
+ </message>
+ <message name="IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT" desc="The text to show in place of reading list article content if the article is not found.">
+ Could not find the requested article.
+ </message>
+ <message name="IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE" desc="The text to show in place of a reading list article title if there is no data found.">
+ Failed to display article.
+ </message>
+ <message name="IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT" desc="The text to show in place of reading list article content if there is no data found.">
+ No data found.
+ </message>
</grit-part>