blob: a44531cc90162284b3f809eacf9a8603545aed01 [file] [log] [blame]
// Copyright 2013 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/distiller_page.h"
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/component_resources.h"
#include "third_party/dom_distiller_js/dom_distiller.pb.h"
#include "third_party/dom_distiller_js/dom_distiller_json_converter.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/gurl.h"
namespace dom_distiller {
namespace {
const char* kOptionsPlaceholder = "$$OPTIONS";
std::string GetDistillerScriptWithOptions(
const dom_distiller::proto::DomDistillerOptions& options) {
std::string script = ResourceBundle::GetSharedInstance()
.GetRawDataResource(IDR_DISTILLER_JS)
.as_string();
if (script.empty()) {
return "";
}
scoped_ptr<base::Value> options_value(
dom_distiller::proto::json::DomDistillerOptions::WriteToValue(options));
std::string options_json;
if (!base::JSONWriter::Write(options_value.get(), &options_json)) {
NOTREACHED();
}
size_t options_offset = script.find(kOptionsPlaceholder);
DCHECK_NE(std::string::npos, options_offset);
DCHECK_EQ(std::string::npos,
script.find(kOptionsPlaceholder, options_offset + 1));
script =
script.replace(options_offset, strlen(kOptionsPlaceholder), options_json);
return script;
}
}
DistilledPageInfo::DistilledPageInfo() {}
DistilledPageInfo::~DistilledPageInfo() {}
DistillerPageFactory::~DistillerPageFactory() {}
DistillerPage::DistillerPage() : ready_(true) {}
DistillerPage::~DistillerPage() {}
void DistillerPage::DistillPage(
const GURL& gurl,
const dom_distiller::proto::DomDistillerOptions options,
const DistillerPageCallback& callback) {
DCHECK(ready_);
// It is only possible to distill one page at a time. |ready_| is reset when
// the callback to OnDistillationDone happens.
ready_ = false;
distiller_page_callback_ = callback;
DistillPageImpl(gurl, GetDistillerScriptWithOptions(options));
}
void DistillerPage::OnDistillationDone(const GURL& page_url,
const base::Value* value) {
DCHECK(!ready_);
ready_ = true;
scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo());
bool found_content = !value->IsType(base::Value::TYPE_NULL);
if (found_content) {
dom_distiller::proto::DomDistillerResult distiller_result =
dom_distiller::proto::json::DomDistillerResult::ReadFromValue(value);
page_info->title = distiller_result.title();
page_info->html = distiller_result.distilled_content().html();
page_info->next_page_url = distiller_result.pagination_info().next_page();
page_info->prev_page_url = distiller_result.pagination_info().prev_page();
for (int i = 0; i < distiller_result.image_urls_size(); ++i) {
const std::string image_url = distiller_result.image_urls(i);
if (GURL(image_url).is_valid()) {
page_info->image_urls.push_back(image_url);
}
}
}
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(
distiller_page_callback_, base::Passed(&page_info), found_content));
}
} // namespace dom_distiller