OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/dom_distiller/core/distiller_page.h" | 5 #include "components/dom_distiller/core/distiller_page.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_writer.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" |
10 #include "grit/component_resources.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" |
11 #include "ui/base/resource/resource_bundle.h" | 16 #include "ui/base/resource/resource_bundle.h" |
12 #include "url/gurl.h" | 17 #include "url/gurl.h" |
13 | 18 |
14 namespace dom_distiller { | 19 namespace dom_distiller { |
15 | 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 |
16 DistilledPageInfo::DistilledPageInfo() {} | 51 DistilledPageInfo::DistilledPageInfo() {} |
17 | 52 |
18 DistilledPageInfo::~DistilledPageInfo() {} | 53 DistilledPageInfo::~DistilledPageInfo() {} |
19 | 54 |
20 DistillerPageFactory::~DistillerPageFactory() {} | 55 DistillerPageFactory::~DistillerPageFactory() {} |
21 | 56 |
22 DistillerPage::DistillerPage() : ready_(true) {} | 57 DistillerPage::DistillerPage() : ready_(true) {} |
23 | 58 |
24 DistillerPage::~DistillerPage() {} | 59 DistillerPage::~DistillerPage() {} |
25 | 60 |
26 void DistillerPage::DistillPage(const GURL& gurl, | 61 void DistillerPage::DistillPage(const GURL& gurl, |
27 const DistillerPageCallback& callback) { | 62 const DistillerPageCallback& callback) { |
28 DCHECK(ready_); | 63 DCHECK(ready_); |
29 // It is only possible to distill one page at a time. |ready_| is reset when | 64 // It is only possible to distill one page at a time. |ready_| is reset when |
30 // the callback to OnDistillationDone happens. | 65 // the callback to OnDistillationDone happens. |
31 ready_ = false; | 66 ready_ = false; |
32 distiller_page_callback_ = callback; | 67 distiller_page_callback_ = callback; |
33 std::string script = ResourceBundle::GetSharedInstance() | 68 dom_distiller::proto::DomDistillerOptions options; |
34 .GetRawDataResource(IDR_DISTILLER_JS) | 69 DistillPageImpl(gurl, GetDistillerScriptWithOptions(options)); |
35 .as_string(); | |
36 DistillPageImpl(gurl, script); | |
37 } | 70 } |
38 | 71 |
39 void DistillerPage::OnDistillationDone(const GURL& page_url, | 72 void DistillerPage::OnDistillationDone(const GURL& page_url, |
40 const base::Value* value) { | 73 const base::Value* value) { |
41 DCHECK(!ready_); | 74 DCHECK(!ready_); |
42 ready_ = true; | 75 ready_ = true; |
| 76 |
43 scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo()); | 77 scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo()); |
44 std::string result; | 78 bool found_content = !value->IsType(base::Value::TYPE_NULL); |
45 const base::ListValue* result_list = NULL; | 79 if (found_content) { |
46 bool found_content = false; | 80 dom_distiller::proto::DomDistillerResult distiller_result = |
47 if (!value->GetAsList(&result_list)) { | 81 dom_distiller::proto::json::DomDistillerResult::ReadFromValue(value); |
48 base::MessageLoop::current()->PostTask( | 82 |
49 FROM_HERE, | 83 page_info->title = distiller_result.title(); |
50 base::Bind(distiller_page_callback_, base::Passed(&page_info), false)); | 84 page_info->html = distiller_result.distilled_content().html(); |
51 } else { | 85 page_info->next_page_url = distiller_result.pagination_info().next_page(); |
52 int i = 0; | 86 page_info->prev_page_url = distiller_result.pagination_info().prev_page(); |
53 for (base::ListValue::const_iterator iter = result_list->begin(); | 87 for (int i = 0; i < distiller_result.image_urls_size(); ++i) { |
54 iter != result_list->end(); | 88 const std::string image_url = distiller_result.image_urls(i); |
55 ++iter, ++i) { | 89 if (GURL(image_url).is_valid()) { |
56 std::string item; | 90 page_info->image_urls.push_back(image_url); |
57 (*iter)->GetAsString(&item); | |
58 // The JavaScript returns an array where the first element is the title, | |
59 // the second element is the article content HTML, and the remaining | |
60 // elements are image URLs referenced in the HTML. | |
61 switch (i) { | |
62 case 0: | |
63 page_info->title = item; | |
64 break; | |
65 case 1: | |
66 page_info->html = item; | |
67 found_content = true; | |
68 break; | |
69 case 2: | |
70 page_info->next_page_url = item; | |
71 break; | |
72 case 3: | |
73 page_info->prev_page_url = item; | |
74 break; | |
75 default: | |
76 if (GURL(item).is_valid()) { | |
77 page_info->image_urls.push_back(item); | |
78 } | |
79 } | 91 } |
80 } | 92 } |
81 base::MessageLoop::current()->PostTask( | |
82 FROM_HERE, | |
83 base::Bind( | |
84 distiller_page_callback_, base::Passed(&page_info), found_content)); | |
85 } | 93 } |
| 94 |
| 95 base::MessageLoop::current()->PostTask( |
| 96 FROM_HERE, |
| 97 base::Bind( |
| 98 distiller_page_callback_, base::Passed(&page_info), found_content)); |
86 } | 99 } |
87 | 100 |
88 } // namespace dom_distiller | 101 } // namespace dom_distiller |
OLD | NEW |