summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authormdjones <mdjones@chromium.org>2015-04-27 09:40:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-27 16:40:48 +0000
commitb9fee24969e63f6b172d62c6a26c56812cb3b697 (patch)
tree93148ee436274c54543f2ce8b844491d86b5a053 /components
parentb120440b979924e5100ee2ff9b484a39d0584c59 (diff)
downloadchromium_src-b9fee24969e63f6b172d62c6a26c56812cb3b697.zip
chromium_src-b9fee24969e63f6b172d62c6a26c56812cb3b697.tar.gz
chromium_src-b9fee24969e63f6b172d62c6a26c56812cb3b697.tar.bz2
Move common distiller code to superclass
This change moves any code related to JavaScript and HTML generation in dom distiller to a superclass that all platforms can use. BUG=472797 Review URL: https://codereview.chromium.org/1101993003 Cr-Commit-Position: refs/heads/master@{#327055}
Diffstat (limited to 'components')
-rw-r--r--components/dom_distiller.gypi2
-rw-r--r--components/dom_distiller/content/dom_distiller_viewer_source.cc172
-rw-r--r--components/dom_distiller/core/BUILD.gn2
-rw-r--r--components/dom_distiller/core/dom_distiller_request_view_base.cc115
-rw-r--r--components/dom_distiller/core/dom_distiller_request_view_base.h87
5 files changed, 248 insertions, 130 deletions
diff --git a/components/dom_distiller.gypi b/components/dom_distiller.gypi
index fa2f4ee..c2bb83d 100644
--- a/components/dom_distiller.gypi
+++ b/components/dom_distiller.gypi
@@ -82,6 +82,8 @@
'dom_distiller/core/dom_distiller_model.cc',
'dom_distiller/core/dom_distiller_model.h',
'dom_distiller/core/dom_distiller_observer.h',
+ 'dom_distiller/core/dom_distiller_request_view_base.cc',
+ 'dom_distiller/core/dom_distiller_request_view_base.h',
'dom_distiller/core/dom_distiller_service.cc',
'dom_distiller/core/dom_distiller_service.h',
'dom_distiller/core/dom_distiller_service_android.cc',
diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.cc b/components/dom_distiller/content/dom_distiller_viewer_source.cc
index 5015464..4483f4b 100644
--- a/components/dom_distiller/content/dom_distiller_viewer_source.cc
+++ b/components/dom_distiller/content/dom_distiller_viewer_source.cc
@@ -14,6 +14,7 @@
#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "components/dom_distiller/core/distilled_page_prefs.h"
+#include "components/dom_distiller/core/dom_distiller_request_view_base.h"
#include "components/dom_distiller/core/dom_distiller_service.h"
#include "components/dom_distiller/core/external_feedback_reporter.h"
#include "components/dom_distiller/core/feedback_reporter.h"
@@ -32,32 +33,44 @@
namespace dom_distiller {
+namespace {
+
+class ContentDataCallback : public DistillerDataCallback {
+ public:
+ ContentDataCallback(const content::URLDataSource::GotDataCallback& callback);
+ // Runs the callback.
+ void RunCallback(std::string& data) override;
+
+ private:
+ // The callback that actually gets run.
+ content::URLDataSource::GotDataCallback callback_;
+};
+
+ContentDataCallback::ContentDataCallback(
+ const content::URLDataSource::GotDataCallback& callback) {
+ callback_ = callback;
+}
+
+void ContentDataCallback::RunCallback(std::string& data) {
+ callback_.Run(base::RefCountedString::TakeString(&data));
+}
+
+} // namespace
+
// Handles receiving data asynchronously for a specific entry, and passing
// it along to the data callback for the data source. Lifetime matches that of
// the current main frame's page in the Viewer instance.
class DomDistillerViewerSource::RequestViewerHandle
- : public ViewRequestDelegate,
- public content::WebContentsObserver,
- public DistilledPagePrefs::Observer {
+ : public DomDistillerRequestViewBase,
+ public content::WebContentsObserver {
public:
- explicit RequestViewerHandle(
- content::WebContents* web_contents,
- const std::string& expected_scheme,
- const std::string& expected_request_path,
- const content::URLDataSource::GotDataCallback& callback,
- DistilledPagePrefs* distilled_page_prefs);
+ RequestViewerHandle(content::WebContents* web_contents,
+ const std::string& expected_scheme,
+ const std::string& expected_request_path,
+ scoped_ptr<ContentDataCallback> callback,
+ DistilledPagePrefs* distilled_page_prefs);
~RequestViewerHandle() override;
- // Flag this request as an error and send the error page template.
- void flagAsErrorPage();
-
- // ViewRequestDelegate implementation:
- void OnArticleReady(const DistilledArticleProto* article_proto) override;
-
- void OnArticleUpdated(ArticleDistillationUpdate article_update) override;
-
- void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle);
-
// content::WebContentsObserver implementation:
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
@@ -70,38 +83,19 @@ class DomDistillerViewerSource::RequestViewerHandle
private:
// Sends JavaScript to the attached Viewer, buffering data if the viewer isn't
// ready.
- void SendJavaScript(const std::string& buffer);
+ void SendJavaScript(const std::string& buffer) override;
// Cancels the current view request. Once called, no updates will be
// propagated to the view, and the request to DomDistillerService will be
// cancelled.
void Cancel();
- // DistilledPagePrefs::Observer implementation:
- void OnChangeFontFamily(
- DistilledPagePrefs::FontFamily new_font_family) override;
- void OnChangeTheme(DistilledPagePrefs::Theme new_theme) override;
-
- // 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_;
-
// The scheme hosting the current view request;
std::string expected_scheme_;
// The query path for the current view request.
std::string expected_request_path_;
- // Holds the callback to where the data retrieved is sent back.
- content::URLDataSource::GotDataCallback callback_;
-
- // Number of pages of the distilled article content that have been rendered by
- // the viewer.
- int page_count_;
-
- // Interface for accessing preferences for distilled pages.
- DistilledPagePrefs* distilled_page_prefs_;
-
// Whether the page is sufficiently initialized to handle updates from the
// distiller.
bool waiting_for_page_ready_;
@@ -109,24 +103,18 @@ class DomDistillerViewerSource::RequestViewerHandle
// Temporary store of pending JavaScript if the page isn't ready to receive
// data from distillation.
std::string buffer_;
-
- // Flag to tell this observer that the web contents are in an error state.
- bool is_error_page_;
};
DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
content::WebContents* web_contents,
const std::string& expected_scheme,
const std::string& expected_request_path,
- const content::URLDataSource::GotDataCallback& callback,
+ scoped_ptr<ContentDataCallback> callback,
DistilledPagePrefs* distilled_page_prefs)
- : expected_scheme_(expected_scheme),
+ : DomDistillerRequestViewBase(callback.Pass(), distilled_page_prefs),
+ expected_scheme_(expected_scheme),
expected_request_path_(expected_request_path),
- callback_(callback),
- page_count_(0),
- distilled_page_prefs_(distilled_page_prefs),
- waiting_for_page_ready_(true),
- is_error_page_(false) {
+ waiting_for_page_ready_(true) {
content::WebContentsObserver::Observe(web_contents);
distilled_page_prefs_->AddObserver(this);
}
@@ -135,14 +123,6 @@ DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
distilled_page_prefs_->RemoveObserver(this);
}
-void DomDistillerViewerSource::RequestViewerHandle::flagAsErrorPage() {
- is_error_page_ = true;
- std::string error_page_html = viewer::GetErrorPageHtml(
- distilled_page_prefs_->GetTheme(),
- distilled_page_prefs_->GetFontFamily());
- callback_.Run(base::RefCountedString::TakeString(&error_page_html));
-}
-
void DomDistillerViewerSource::RequestViewerHandle::SendJavaScript(
const std::string& buffer) {
if (waiting_for_page_ready_) {
@@ -190,7 +170,7 @@ void DomDistillerViewerSource::RequestViewerHandle::Cancel() {
void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
- if (is_error_page_) {
+ if (IsErrorPage()) {
waiting_for_page_ready_ = false;
SendJavaScript(viewer::GetErrorPageJs());
SendJavaScript(viewer::GetShowFeedbackFormJs());
@@ -209,76 +189,6 @@ void DomDistillerViewerSource::RequestViewerHandle::DidFinishLoad(
buffer_.clear();
}
-void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady(
- const DistilledArticleProto* article_proto) {
- // TODO(mdjones): Move this logic to super class so it can be used in both
- // android and IOS. http://crbug.com/472797
- if (page_count_ == 0) {
- std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml(
- &article_proto->pages(0),
- distilled_page_prefs_->GetTheme(),
- distilled_page_prefs_->GetFontFamily());
- callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
- // Send first page to client.
- SendJavaScript(viewer::GetUnsafeArticleContentJs(article_proto));
- // If any content was loaded, show the feedback form.
- SendJavaScript(viewer::GetShowFeedbackFormJs());
- } else if (page_count_ == article_proto->pages_size()) {
- // We may still be showing the "Loading" indicator.
- SendJavaScript(viewer::GetToggleLoadingIndicatorJs(true));
- } else {
- // It's possible that we didn't get some incremental updates from the
- // distiller. Ensure all remaining pages are flushed to the viewer.
- for (;page_count_ < article_proto->pages_size(); page_count_++) {
- const DistilledPageProto& page = article_proto->pages(page_count_);
- SendJavaScript(
- viewer::GetUnsafeIncrementalDistilledPageJs(
- &page,
- page_count_ == article_proto->pages_size()));
- }
- }
- // No need to hold on to the ViewerHandle now that distillation is complete.
- viewer_handle_.reset();
-}
-
-void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated(
- ArticleDistillationUpdate article_update) {
- for (;page_count_ < static_cast<int>(article_update.GetPagesSize());
- page_count_++) {
- const DistilledPageProto& page =
- article_update.GetDistilledPage(page_count_);
- // Send the page content to the client. This will execute after the page is
- // ready.
- SendJavaScript(viewer::GetUnsafeIncrementalDistilledPageJs(&page, false));
-
- if (page_count_ == 0) {
- // This is the first page, so send Viewer page scaffolding too.
- std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml(
- &page,
- distilled_page_prefs_->GetTheme(),
- distilled_page_prefs_->GetFontFamily());
- callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
- // If any content was loaded, show the feedback form.
- SendJavaScript(viewer::GetShowFeedbackFormJs());
- }
- }
-}
-
-void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle(
- scoped_ptr<ViewerHandle> viewer_handle) {
- viewer_handle_ = viewer_handle.Pass();
-}
-
-void DomDistillerViewerSource::RequestViewerHandle::OnChangeTheme(
- DistilledPagePrefs::Theme new_theme) {
- SendJavaScript(viewer::GetDistilledPageThemeJs(new_theme));
-}
-
-void DomDistillerViewerSource::RequestViewerHandle::OnChangeFontFamily(
- DistilledPagePrefs::FontFamily new_font) {
- SendJavaScript(viewer::GetDistilledPageFontFamilyJs(new_font));
-}
-
DomDistillerViewerSource::DomDistillerViewerSource(
DomDistillerServiceInterface* dom_distiller_service,
const std::string& scheme,
@@ -338,10 +248,12 @@ void DomDistillerViewerSource::StartDataRequest(
DCHECK(web_contents);
// An empty |path| is invalid, but guard against it. If not empty, assume
// |path| starts with '?', which is stripped away.
+ scoped_ptr<ContentDataCallback> data_callback(
+ new ContentDataCallback(callback));
const std::string path_after_query_separator =
path.size() > 0 ? path.substr(1) : "";
RequestViewerHandle* request_viewer_handle = new RequestViewerHandle(
- web_contents, scheme_, path_after_query_separator, callback,
+ web_contents, scheme_, path_after_query_separator, data_callback.Pass(),
dom_distiller_service_->GetDistilledPagePrefs());
scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
dom_distiller_service_, path, request_viewer_handle,
@@ -354,7 +266,7 @@ void DomDistillerViewerSource::StartDataRequest(
// after receiving the callback.
request_viewer_handle->TakeViewerHandle(viewer_handle.Pass());
} else {
- request_viewer_handle->flagAsErrorPage();
+ request_viewer_handle->FlagAsErrorPage();
}
};
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn
index a9b1cda..565f1fe 100644
--- a/components/dom_distiller/core/BUILD.gn
+++ b/components/dom_distiller/core/BUILD.gn
@@ -32,6 +32,8 @@ source_set("core") {
"dom_distiller_model.cc",
"dom_distiller_model.h",
"dom_distiller_observer.h",
+ "dom_distiller_request_view_base.cc",
+ "dom_distiller_request_view_base.h",
"dom_distiller_service.cc",
"dom_distiller_service.h",
"dom_distiller_store.cc",
diff --git a/components/dom_distiller/core/dom_distiller_request_view_base.cc b/components/dom_distiller/core/dom_distiller_request_view_base.cc
new file mode 100644
index 0000000..3488d6b
--- /dev/null
+++ b/components/dom_distiller/core/dom_distiller_request_view_base.cc
@@ -0,0 +1,115 @@
+// Copyright 2015 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.
+
+#include "components/dom_distiller/core/dom_distiller_request_view_base.h"
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/dom_distiller/core/distilled_page_prefs.h"
+#include "components/dom_distiller/core/dom_distiller_service.h"
+#include "components/dom_distiller/core/task_tracker.h"
+#include "components/dom_distiller/core/url_constants.h"
+#include "components/dom_distiller/core/viewer.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/url_data_source.h"
+#include "net/base/url_util.h"
+#include "net/url_request/url_request.h"
+
+namespace dom_distiller {
+
+DomDistillerRequestViewBase::DomDistillerRequestViewBase(
+ scoped_ptr<DistillerDataCallback> callback,
+ DistilledPagePrefs* distilled_page_prefs)
+ : callback_(callback.Pass()),
+ page_count_(0),
+ distilled_page_prefs_(distilled_page_prefs),
+ is_error_page_(false) {
+}
+
+DomDistillerRequestViewBase::~DomDistillerRequestViewBase() {
+}
+
+void DomDistillerRequestViewBase::FlagAsErrorPage() {
+ is_error_page_ = true;
+ std::string error_page_html =
+ viewer::GetErrorPageHtml(distilled_page_prefs_->GetTheme(),
+ distilled_page_prefs_->GetFontFamily());
+ callback_->RunCallback(error_page_html);
+}
+
+bool DomDistillerRequestViewBase::IsErrorPage() {
+ return is_error_page_;
+}
+
+void DomDistillerRequestViewBase::OnArticleReady(
+ const DistilledArticleProto* article_proto) {
+ if (page_count_ == 0) {
+ std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml(
+ &article_proto->pages(0), distilled_page_prefs_->GetTheme(),
+ distilled_page_prefs_->GetFontFamily());
+ callback_->RunCallback(unsafe_page_html);
+ // Send first page to client.
+ SendJavaScript(viewer::GetUnsafeArticleContentJs(article_proto));
+ // If any content was loaded, show the feedback form.
+ SendJavaScript(viewer::GetShowFeedbackFormJs());
+ } else if (page_count_ == article_proto->pages_size()) {
+ // We may still be showing the "Loading" indicator.
+ SendJavaScript(viewer::GetToggleLoadingIndicatorJs(true));
+ } else {
+ // It's possible that we didn't get some incremental updates from the
+ // distiller. Ensure all remaining pages are flushed to the viewer.
+ for (; page_count_ < article_proto->pages_size(); page_count_++) {
+ const DistilledPageProto& page = article_proto->pages(page_count_);
+ SendJavaScript(viewer::GetUnsafeIncrementalDistilledPageJs(
+ &page, page_count_ == article_proto->pages_size()));
+ }
+ }
+ // No need to hold on to the ViewerHandle now that distillation is complete.
+ viewer_handle_.reset();
+}
+
+void DomDistillerRequestViewBase::OnArticleUpdated(
+ ArticleDistillationUpdate article_update) {
+ for (; page_count_ < static_cast<int>(article_update.GetPagesSize());
+ page_count_++) {
+ const DistilledPageProto& page =
+ article_update.GetDistilledPage(page_count_);
+ // Send the page content to the client. This will execute after the page is
+ // ready.
+ SendJavaScript(viewer::GetUnsafeIncrementalDistilledPageJs(&page, false));
+
+ if (page_count_ == 0) {
+ // This is the first page, so send Viewer page scaffolding too.
+ std::string unsafe_page_html = viewer::GetUnsafeArticleTemplateHtml(
+ &page, distilled_page_prefs_->GetTheme(),
+ distilled_page_prefs_->GetFontFamily());
+ callback_->RunCallback(unsafe_page_html);
+ // If any content was loaded, show the feedback form.
+ SendJavaScript(viewer::GetShowFeedbackFormJs());
+ }
+ }
+}
+
+void DomDistillerRequestViewBase::OnChangeTheme(
+ DistilledPagePrefs::Theme new_theme) {
+ SendJavaScript(viewer::GetDistilledPageThemeJs(new_theme));
+}
+
+void DomDistillerRequestViewBase::OnChangeFontFamily(
+ DistilledPagePrefs::FontFamily new_font) {
+ SendJavaScript(viewer::GetDistilledPageFontFamilyJs(new_font));
+}
+
+void DomDistillerRequestViewBase::TakeViewerHandle(
+ scoped_ptr<ViewerHandle> viewer_handle) {
+ viewer_handle_ = viewer_handle.Pass();
+}
+
+} // namespace dom_distiller
diff --git a/components/dom_distiller/core/dom_distiller_request_view_base.h b/components/dom_distiller/core/dom_distiller_request_view_base.h
new file mode 100644
index 0000000..16b8ca7
--- /dev/null
+++ b/components/dom_distiller/core/dom_distiller_request_view_base.h
@@ -0,0 +1,87 @@
+// Copyright 2015 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.
+
+#ifndef COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_REQUEST_VIEW_BASE_H_
+#define COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_REQUEST_VIEW_BASE_H_
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/dom_distiller/core/distilled_page_prefs.h"
+#include "components/dom_distiller/core/dom_distiller_service.h"
+#include "components/dom_distiller/core/task_tracker.h"
+#include "components/dom_distiller/core/viewer.h"
+#include "content/public/browser/url_data_source.h"
+#include "net/base/url_util.h"
+
+namespace dom_distiller {
+
+// This interface is used to abstract the data callback from the distiller. The
+// callbacks for different platforms have different numbers of parameters
+// (namely iOS and Android) which makes this necessary.
+class DistillerDataCallback {
+ public:
+ virtual ~DistillerDataCallback(){};
+ virtual void RunCallback(std::string& data) = 0;
+};
+
+// Handles receiving data asynchronously for a specific entry, and passing
+// it along to the data callback for the data source. Lifetime matches that of
+// the current main frame's page in the Viewer instance.
+class DomDistillerRequestViewBase
+ : public ViewRequestDelegate,
+ public DistilledPagePrefs::Observer {
+ public:
+ explicit DomDistillerRequestViewBase(
+ scoped_ptr<DistillerDataCallback> callback,
+ DistilledPagePrefs* distilled_page_prefs);
+ ~DomDistillerRequestViewBase() override;
+
+ // Flag this request as an error and send the error page template.
+ void FlagAsErrorPage();
+ // Get if this viewer is in an error state.
+ bool IsErrorPage();
+
+ // ViewRequestDelegate implementation:
+ void OnArticleReady(const DistilledArticleProto* article_proto) override;
+
+ void OnArticleUpdated(ArticleDistillationUpdate article_update) override;
+
+ void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle);
+
+ protected:
+ // DistilledPagePrefs::Observer implementation:
+ void OnChangeFontFamily(
+ DistilledPagePrefs::FontFamily new_font_family) override;
+ void OnChangeTheme(DistilledPagePrefs::Theme new_theme) override;
+
+ // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't
+ // ready.
+ virtual void SendJavaScript(const std::string& buffer) = 0;
+
+ // 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_;
+
+ // Holds the callback to where the data retrieved is sent back.
+ scoped_ptr<DistillerDataCallback> callback_;
+
+ // Number of pages of the distilled article content that have been rendered by
+ // the viewer.
+ int page_count_;
+
+ // Interface for accessing preferences for distilled pages.
+ DistilledPagePrefs* distilled_page_prefs_;
+
+ // Flag to tell this observer that the web contents are in an error state.
+ bool is_error_page_;
+};
+
+} // namespace dom_distiller
+
+#endif // COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_REQUEST_VIEW_BASE_H_