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" | |
13 #include "dom_distiller_js/dom_distiller.pb.h" | |
14 #include "dom_distiller_js/dom_distiller_json_converter.h" | |
10 #include "grit/component_resources.h" | 15 #include "grit/component_resources.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 dom_distiller::proto::DomDistillerOptions options) { | |
Yaron
2014/05/09 01:00:55
const&
cjhopman
2014/05/09 01:55:06
Done.
| |
27 std::string script = ResourceBundle::GetSharedInstance() | |
28 .GetRawDataResource(IDR_DISTILLER_JS) | |
29 .as_string(); | |
30 scoped_ptr<base::Value> options_value( | |
31 dom_distiller::proto::json::DomDistillerOptions::WriteToValue(options)); | |
32 std::string options_json; | |
33 if (!base::JSONWriter::Write(options_value.get(), &options_json)) { | |
34 NOTREACHED(); | |
35 } | |
36 size_t options_offset = script.find(kOptionsPlaceholder); | |
Yaron
2014/05/09 01:00:55
Instead of rolling your own, why not use base::Rep
cjhopman
2014/05/09 01:55:06
ReplaceStringPlaceholders is rather dangerous, it
| |
37 DCHECK_NE(std::string::npos, options_offset); | |
38 DCHECK_EQ(std::string::npos, | |
39 script.find(kOptionsPlaceholder, options_offset + 1)); | |
40 script = | |
41 script.replace(options_offset, strlen(kOptionsPlaceholder), options_json); | |
42 return script; | |
43 } | |
44 | |
45 } | |
46 | |
16 DistilledPageInfo::DistilledPageInfo() {} | 47 DistilledPageInfo::DistilledPageInfo() {} |
17 | 48 |
18 DistilledPageInfo::~DistilledPageInfo() {} | 49 DistilledPageInfo::~DistilledPageInfo() {} |
19 | 50 |
20 DistillerPageFactory::~DistillerPageFactory() {} | 51 DistillerPageFactory::~DistillerPageFactory() {} |
21 | 52 |
22 DistillerPage::DistillerPage() : ready_(true) {} | 53 DistillerPage::DistillerPage() : ready_(true) {} |
23 | 54 |
24 DistillerPage::~DistillerPage() {} | 55 DistillerPage::~DistillerPage() {} |
25 | 56 |
26 void DistillerPage::DistillPage(const GURL& gurl, | 57 void DistillerPage::DistillPage(const GURL& gurl, |
27 const DistillerPageCallback& callback) { | 58 const DistillerPageCallback& callback) { |
28 DCHECK(ready_); | 59 DCHECK(ready_); |
29 // It is only possible to distill one page at a time. |ready_| is reset when | 60 // It is only possible to distill one page at a time. |ready_| is reset when |
30 // the callback to OnDistillationDone happens. | 61 // the callback to OnDistillationDone happens. |
31 ready_ = false; | 62 ready_ = false; |
32 distiller_page_callback_ = callback; | 63 distiller_page_callback_ = callback; |
33 std::string script = ResourceBundle::GetSharedInstance() | 64 dom_distiller::proto::DomDistillerOptions options; |
34 .GetRawDataResource(IDR_DISTILLER_JS) | 65 DistillPageImpl(gurl, GetDistillerScriptWithOptions(options)); |
35 .as_string(); | |
36 DistillPageImpl(gurl, script); | |
37 } | 66 } |
38 | 67 |
39 void DistillerPage::OnDistillationDone(const GURL& page_url, | 68 void DistillerPage::OnDistillationDone(const GURL& page_url, |
40 const base::Value* value) { | 69 const base::Value* value) { |
41 DCHECK(!ready_); | 70 DCHECK(!ready_); |
42 ready_ = true; | 71 ready_ = true; |
72 | |
43 scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo()); | 73 scoped_ptr<DistilledPageInfo> page_info(new DistilledPageInfo()); |
44 std::string result; | 74 bool found_content = !value->IsType(base::Value::TYPE_NULL); |
45 const base::ListValue* result_list = NULL; | 75 if (found_content) { |
46 bool found_content = false; | 76 dom_distiller::proto::DomDistillerResult distiller_result = |
47 if (!value->GetAsList(&result_list)) { | 77 dom_distiller::proto::json::DomDistillerResult::ReadFromValue(value); |
48 base::MessageLoop::current()->PostTask( | 78 |
49 FROM_HERE, | 79 page_info->title = distiller_result.title(); |
50 base::Bind(distiller_page_callback_, base::Passed(&page_info), false)); | 80 page_info->html = distiller_result.distilled_content().html(); |
51 } else { | 81 page_info->next_page_url = distiller_result.pagination_info().next_page(); |
52 int i = 0; | 82 page_info->prev_page_url = distiller_result.pagination_info().prev_page(); |
53 for (base::ListValue::const_iterator iter = result_list->begin(); | 83 for (int i = 0; i < distiller_result.image_urls_size(); ++i) { |
54 iter != result_list->end(); | 84 const std::string image_url = distiller_result.image_urls(i); |
55 ++iter, ++i) { | 85 if (GURL(image_url).is_valid()) { |
56 std::string item; | 86 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 } | 87 } |
80 } | 88 } |
81 base::MessageLoop::current()->PostTask( | |
82 FROM_HERE, | |
83 base::Bind( | |
84 distiller_page_callback_, base::Passed(&page_info), found_content)); | |
85 } | 89 } |
90 | |
91 base::MessageLoop::current()->PostTask( | |
92 FROM_HERE, | |
93 base::Bind( | |
94 distiller_page_callback_, base::Passed(&page_info), found_content)); | |
86 } | 95 } |
87 | 96 |
88 } // namespace dom_distiller | 97 } // namespace dom_distiller |
OLD | NEW |