Home | History | Annotate | Download | only in core
      1 // Copyright 2013 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.
      4 
      5 #include "components/dom_distiller/core/distiller_page.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/json/json_writer.h"
      9 #include "base/logging.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "grit/component_resources.h"
     14 #include "third_party/dom_distiller_js/dom_distiller.pb.h"
     15 #include "third_party/dom_distiller_js/dom_distiller_json_converter.h"
     16 #include "ui/base/resource/resource_bundle.h"
     17 #include "url/gurl.h"
     18 
     19 namespace dom_distiller {
     20 
     21 namespace {
     22 
     23 const char* kOptionsPlaceholder = "$$OPTIONS";
     24 
     25 std::string GetDistillerScriptWithOptions(
     26     const dom_distiller::proto::DomDistillerOptions& options) {
     27   std::string script = ResourceBundle::GetSharedInstance()
     28                            .GetRawDataResource(IDR_DISTILLER_JS)
     29                            .as_string();
     30   if (script.empty()) {
     31     return "";
     32   }
     33 
     34   scoped_ptr<base::Value> options_value(
     35       dom_distiller::proto::json::DomDistillerOptions::WriteToValue(options));
     36   std::string options_json;
     37   if (!base::JSONWriter::Write(options_value.get(), &options_json)) {
     38     NOTREACHED();
     39   }
     40   size_t options_offset = script.find(kOptionsPlaceholder);
     41   DCHECK_NE(std::string::npos, options_offset);
     42   DCHECK_EQ(std::string::npos,
     43             script.find(kOptionsPlaceholder, options_offset + 1));
     44   script =
     45       script.replace(options_offset, strlen(kOptionsPlaceholder), options_json);
     46   return script;
     47 }
     48 
     49 }
     50 
     51 DistilledPageInfo::DistilledPageInfo() {}
     52 
     53 DistilledPageInfo::~DistilledPageInfo() {}
     54 
     55 DistillerPageFactory::~DistillerPageFactory() {}
     56 
     57 DistillerPage::DistillerPage() : ready_(true) {}
     58 
     59 DistillerPage::~DistillerPage() {}
     60 
     61 void DistillerPage::DistillPage(
     62     const GURL& gurl,
     63     const dom_distiller::proto::DomDistillerOptions options,
     64     const DistillerPageCallback& callback) {
     65   DCHECK(ready_);
     66   // It is only possible to distill one page at a time. |ready_| is reset when
     67   // the callback to OnDistillationDone happens.
     68   ready_ = false;
     69   distiller_page_callback_ = callback;
     70   DistillPageImpl(gurl, GetDistillerScriptWithOptions(options));
     71 }
     72 
     73 void DistillerPage::OnDistillationDone(const GURL& page_url,
     74                                        const base::Value* value) {
     75   DCHECK(!ready_);
     76   ready_ = true;
     77 
     78   scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo());
     79   bool found_content = !value->IsType(base::Value::TYPE_NULL);
     80   if (found_content) {
     81     dom_distiller::proto::DomDistillerResult distiller_result =
     82         dom_distiller::proto::json::DomDistillerResult::ReadFromValue(value);
     83 
     84     page_info->title = distiller_result.title();
     85     page_info->html = distiller_result.distilled_content().html();
     86     page_info->next_page_url = distiller_result.pagination_info().next_page();
     87     page_info->prev_page_url = distiller_result.pagination_info().prev_page();
     88     for (int i = 0; i < distiller_result.image_urls_size(); ++i) {
     89       const std::string image_url = distiller_result.image_urls(i);
     90       if (GURL(image_url).is_valid()) {
     91         page_info->image_urls.push_back(image_url);
     92       }
     93     }
     94   }
     95 
     96   base::MessageLoop::current()->PostTask(
     97       FROM_HERE,
     98       base::Bind(
     99           distiller_page_callback_, base::Passed(&page_info), found_content));
    100 }
    101 
    102 }  // namespace dom_distiller
    103