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
3 // found in the LICENSE file.
5 #include "components/dom_distiller/core/viewer.h"
10 #include "base/json/json_writer.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_util.h"
13 #include "components/dom_distiller/core/dom_distiller_service.h"
14 #include "components/dom_distiller/core/proto/distilled_article.pb.h"
15 #include "components/dom_distiller/core/proto/distilled_page.pb.h"
16 #include "components/dom_distiller/core/task_tracker.h"
17 #include "components/dom_distiller/core/url_constants.h"
18 #include "components/dom_distiller/core/url_utils.h"
19 #include "grit/component_resources.h"
20 #include "grit/components_strings.h"
21 #include "net/base/escape.h"
22 #include "net/url_request/url_request.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/resource/resource_bundle.h"
27 namespace dom_distiller
{
31 std::string
ReplaceHtmlTemplateValues(
32 const std::string
& title
,
33 const std::string
& content
,
34 const std::string
& loading_indicator_class
,
35 const std::string
& original_url
) {
36 base::StringPiece html_template
=
37 ResourceBundle::GetSharedInstance().GetRawDataResource(
38 IDR_DOM_DISTILLER_VIEWER_HTML
);
39 std::vector
<std::string
> substitutions
;
40 substitutions
.push_back(title
); // $1
41 substitutions
.push_back(kViewerCssPath
); // $2
42 substitutions
.push_back(kViewerJsPath
); // $3
43 substitutions
.push_back(title
); // $4
44 substitutions
.push_back(content
); // $5
45 substitutions
.push_back(loading_indicator_class
); // $6
46 substitutions
.push_back(
47 l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_LOADING_STRING
)); // $7
48 substitutions
.push_back(original_url
); // $8
49 substitutions
.push_back(
50 l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_VIEW_ORIGINAL
)); // $9
51 return ReplaceStringPlaceholders(html_template
, substitutions
, NULL
);
58 const std::string
GetUnsafeIncrementalDistilledPageJs(
59 const DistilledPageProto
* page_proto
,
60 const bool is_last_page
) {
62 base::StringValue
value(page_proto
->html());
63 base::JSONWriter::Write(&value
, &output
);
64 std::string
page_update("addToPage(");
65 page_update
+= output
+ ");";
66 return page_update
+ GetToggleLoadingIndicatorJs(
71 const std::string
GetToggleLoadingIndicatorJs(const bool is_last_page
) {
73 return "showLoadingIndicator(true);";
75 return "showLoadingIndicator(false);";
78 const std::string
GetUnsafePartialArticleHtml(
79 const DistilledPageProto
* page_proto
) {
81 std::string title
= net::EscapeForHTML(page_proto
->title());
82 std::ostringstream unsafe_output_stream
;
83 unsafe_output_stream
<< page_proto
->html();
84 std::string unsafe_article_html
= unsafe_output_stream
.str();
85 std::string original_url
= page_proto
->url();
86 return ReplaceHtmlTemplateValues(title
,
92 const std::string
GetUnsafeArticleHtml(
93 const DistilledArticleProto
* article_proto
) {
94 DCHECK(article_proto
);
96 std::string unsafe_article_html
;
97 if (article_proto
->has_title() && article_proto
->pages_size() > 0 &&
98 article_proto
->pages(0).has_html()) {
99 title
= net::EscapeForHTML(article_proto
->title());
100 std::ostringstream unsafe_output_stream
;
101 for (int page_num
= 0; page_num
< article_proto
->pages_size(); ++page_num
) {
102 unsafe_output_stream
<< article_proto
->pages(page_num
).html();
104 unsafe_article_html
= unsafe_output_stream
.str();
106 title
= l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE
);
107 unsafe_article_html
=
108 l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT
);
111 std::string original_url
;
112 if (article_proto
->pages_size() > 0 && article_proto
->pages(0).has_url()) {
113 original_url
= article_proto
->pages(0).url();
116 return ReplaceHtmlTemplateValues(title
,
122 const std::string
GetErrorPageHtml() {
123 std::string title
= l10n_util::GetStringUTF8(
124 IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE
);
125 std::string content
= l10n_util::GetStringUTF8(
126 IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT
);
127 return ReplaceHtmlTemplateValues(title
, content
, "hidden", "");
130 const std::string
GetCss() {
131 return ResourceBundle::GetSharedInstance()
132 .GetRawDataResource(IDR_DISTILLER_CSS
)
136 const std::string
GetJavaScript() {
137 return ResourceBundle::GetSharedInstance()
138 .GetRawDataResource(IDR_DOM_DISTILLER_VIEWER_JS
)
142 scoped_ptr
<ViewerHandle
> CreateViewRequest(
143 DomDistillerServiceInterface
* dom_distiller_service
,
144 const std::string
& path
,
145 ViewRequestDelegate
* view_request_delegate
) {
146 std::string entry_id
=
147 url_utils::GetValueForKeyInUrlPathQuery(path
, kEntryIdKey
);
148 bool has_valid_entry_id
= !entry_id
.empty();
149 entry_id
= StringToUpperASCII(entry_id
);
151 std::string requested_url_str
=
152 url_utils::GetValueForKeyInUrlPathQuery(path
, kUrlKey
);
153 GURL
requested_url(requested_url_str
);
154 bool has_valid_url
= url_utils::IsUrlDistillable(requested_url
);
156 if (has_valid_entry_id
&& has_valid_url
) {
157 // It is invalid to specify a query param for both |kEntryIdKey| and
159 return scoped_ptr
<ViewerHandle
>();
162 if (has_valid_entry_id
) {
163 return dom_distiller_service
->ViewEntry(view_request_delegate
,
164 dom_distiller_service
165 ->CreateDefaultDistillerPage(),
167 } else if (has_valid_url
) {
168 return dom_distiller_service
->ViewUrl(view_request_delegate
,
169 dom_distiller_service
170 ->CreateDefaultDistillerPage(),
171 requested_url
).Pass();
174 // It is invalid to not specify a query param for |kEntryIdKey| or |kUrlKey|.
175 return scoped_ptr
<ViewerHandle
>();
178 } // namespace viewer
180 } // namespace dom_distiller