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/webui/dom_distiller_handler.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/values.h" 11 #include "components/dom_distiller/core/dom_distiller_service.h" 12 #include "components/dom_distiller/core/proto/distilled_page.pb.h" 13 #include "components/dom_distiller/core/url_utils.h" 14 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_ui.h" 16 #include "net/base/escape.h" 17 #include "url/gurl.h" 18 19 namespace dom_distiller { 20 21 namespace { 22 23 GURL GetViewUrlFromArgs(const std::string& scheme, 24 const base::ListValue* args) { 25 std::string url; 26 if (args->GetString(0, &url)) { 27 const GURL gurl(url); 28 if (url_utils::IsUrlDistillable(gurl)) { 29 return url_utils::GetDistillerViewUrlFromUrl(scheme, gurl); 30 } 31 } 32 return GURL(); 33 } 34 35 } // namespace 36 37 DomDistillerHandler::DomDistillerHandler(DomDistillerService* service, 38 const std::string& scheme) 39 : service_(service), article_scheme_(scheme), weak_ptr_factory_(this) {} 40 41 DomDistillerHandler::~DomDistillerHandler() {} 42 43 void DomDistillerHandler::RegisterMessages() { 44 web_ui()->RegisterMessageCallback( 45 "requestEntries", 46 base::Bind(&DomDistillerHandler::HandleRequestEntries, 47 base::Unretained(this))); 48 web_ui()->RegisterMessageCallback( 49 "addArticle", 50 base::Bind(&DomDistillerHandler::HandleAddArticle, 51 base::Unretained(this))); 52 web_ui()->RegisterMessageCallback( 53 "selectArticle", 54 base::Bind(&DomDistillerHandler::HandleSelectArticle, 55 base::Unretained(this))); 56 web_ui()->RegisterMessageCallback( 57 "viewUrl", 58 base::Bind(&DomDistillerHandler::HandleViewUrl, base::Unretained(this))); 59 } 60 61 void DomDistillerHandler::HandleAddArticle(const base::ListValue* args) { 62 std::string url; 63 args->GetString(0, &url); 64 GURL gurl(url); 65 if (gurl.is_valid()) { 66 service_->AddToList( 67 gurl, 68 service_->CreateDefaultDistillerPage( 69 web_ui()->GetWebContents()->GetContainerBounds().size()), 70 base::Bind(base::Bind(&DomDistillerHandler::OnArticleAdded, 71 base::Unretained(this)))); 72 } else { 73 web_ui()->CallJavascriptFunction("domDistiller.onArticleAddFailed"); 74 } 75 } 76 77 void DomDistillerHandler::HandleViewUrl(const base::ListValue* args) { 78 GURL view_url = GetViewUrlFromArgs(article_scheme_, args); 79 if (view_url.is_valid()) { 80 web_ui()->GetWebContents()->GetController().LoadURL( 81 view_url, 82 content::Referrer(), 83 ui::PAGE_TRANSITION_GENERATED, 84 std::string()); 85 } else { 86 web_ui()->CallJavascriptFunction("domDistiller.onViewUrlFailed"); 87 } 88 } 89 90 void DomDistillerHandler::HandleSelectArticle(const base::ListValue* args) { 91 std::string entry_id; 92 args->GetString(0, &entry_id); 93 GURL url = 94 url_utils::GetDistillerViewUrlFromEntryId(article_scheme_, entry_id); 95 DCHECK(url.is_valid()); 96 web_ui()->GetWebContents()->GetController().LoadURL( 97 url, 98 content::Referrer(), 99 ui::PAGE_TRANSITION_GENERATED, 100 std::string()); 101 } 102 103 void DomDistillerHandler::HandleRequestEntries(const base::ListValue* args) { 104 base::ListValue entries; 105 const std::vector<ArticleEntry>& entries_specifics = service_->GetEntries(); 106 for (std::vector<ArticleEntry>::const_iterator it = entries_specifics.begin(); 107 it != entries_specifics.end(); 108 ++it) { 109 const ArticleEntry& article = *it; 110 DCHECK(IsEntryValid(article)); 111 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); 112 entry->SetString("entry_id", article.entry_id()); 113 std::string title = (!article.has_title() || article.title().empty()) 114 ? article.entry_id() 115 : article.title(); 116 entry->SetString("title", net::EscapeForHTML(title)); 117 entries.Append(entry.release()); 118 } 119 // TODO(nyquist): Write a test that ensures we sanitize the data we send. 120 web_ui()->CallJavascriptFunction("domDistiller.onReceivedEntries", entries); 121 } 122 123 void DomDistillerHandler::OnArticleAdded(bool article_available) { 124 // TODO(nyquist): Update this function. 125 if (article_available) { 126 HandleRequestEntries(NULL); 127 } else { 128 web_ui()->CallJavascriptFunction("domDistiller.onArticleAddFailed"); 129 } 130 } 131 132 } // namespace dom_distiller 133