suggestions_source.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 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 "chrome/browser/search/suggestions/suggestions_source.h" 6 7#include <vector> 8 9#include "base/bind.h" 10#include "base/memory/ref_counted_memory.h" 11#include "base/strings/string16.h" 12#include "base/strings/string_util.h" 13#include "base/strings/utf_string_conversions.h" 14#include "chrome/browser/profiles/profile.h" 15#include "chrome/browser/search/instant_io_context.h" 16#include "chrome/browser/search/suggestions/proto/suggestions.pb.h" 17#include "chrome/browser/search/suggestions/suggestions_service.h" 18#include "chrome/browser/search/suggestions/suggestions_service_factory.h" 19#include "chrome/common/url_constants.h" 20#include "net/base/escape.h" 21#include "net/url_request/url_request.h" 22#include "url/gurl.h" 23 24namespace suggestions { 25 26namespace { 27 28const char kHtmlHeader[] = 29 "<!DOCTYPE html>\n<html>\n<head>\n<title>Suggestions</title>\n" 30 "<meta charset=\"utf-8\">\n" 31 "<style type=\"text/css\">\nli {white-space: nowrap;}\n</style>\n"; 32const char kHtmlBody[] = "</head>\n<body>\n"; 33const char kHtmlFooter[] = "</body>\n</html>\n"; 34 35} // namespace 36 37SuggestionsSource::SuggestionsSource(Profile* profile) 38 : profile_(profile), 39 weak_ptr_factory_(this) { 40} 41 42SuggestionsSource::~SuggestionsSource() { 43} 44 45std::string SuggestionsSource::GetSource() const { 46 return chrome::kChromeUISuggestionsHost; 47} 48 49void SuggestionsSource::StartDataRequest( 50 const std::string& path, 51 int render_process_id, 52 int render_frame_id, 53 const content::URLDataSource::GotDataCallback& callback) { 54 SuggestionsServiceFactory* suggestions_service_factory = 55 SuggestionsServiceFactory::GetInstance(); 56 57 SuggestionsService* suggestions_service( 58 suggestions_service_factory->GetForProfile(profile_)); 59 60 // If SuggestionsService is unavailable, then SuggestionsSource should not 61 // have been instantiated in the first place. 62 DCHECK(suggestions_service != NULL); 63 64 suggestions_service->FetchSuggestionsData( 65 base::Bind(&SuggestionsSource::OnSuggestionsAvailable, 66 weak_ptr_factory_.GetWeakPtr(), callback)); 67} 68 69std::string SuggestionsSource::GetMimeType(const std::string& path) const { 70 return "text/html"; 71} 72 73base::MessageLoop* SuggestionsSource::MessageLoopForRequestPath( 74 const std::string& path) const { 75 // This can be accessed from the IO thread. 76 return content::URLDataSource::MessageLoopForRequestPath(path); 77} 78 79bool SuggestionsSource::ShouldServiceRequest( 80 const net::URLRequest* request) const { 81 if (request->url().SchemeIs(chrome::kChromeSearchScheme)) 82 return InstantIOContext::ShouldServiceRequest(request); 83 return URLDataSource::ShouldServiceRequest(request); 84} 85 86void SuggestionsSource::OnSuggestionsAvailable( 87 const content::URLDataSource::GotDataCallback& callback, 88 const SuggestionsProfile& suggestions_profile) { 89 // Render HTML. 90 std::vector<std::string> out; 91 out.push_back(kHtmlHeader); 92 out.push_back(kHtmlBody); 93 out.push_back("<h1>Suggestions</h1>\n"); 94 95 size_t size = suggestions_profile.suggestions_size(); 96 if (size == 0) { 97 out.push_back("<p>You have no suggestions.</p>\n"); 98 } else { 99 out.push_back("<ol>\n"); 100 for (size_t i = 0; i < size; ++i) { 101 const ChromeSuggestion& suggestion = suggestions_profile.suggestions(i); 102 std::string line; 103 line.append("<li><a href=\""); 104 line.append(net::EscapeForHTML(suggestion.url())); 105 line.append("\" target=\"_blank\">"); 106 line.append(net::EscapeForHTML(suggestion.title())); 107 line.append("</a></li>\n"); 108 out.push_back(line); 109 } 110 out.push_back("</ol>\n"); 111 } 112 out.push_back(kHtmlFooter); 113 114 std::string out_html = JoinString(out, ""); 115 callback.Run(base::RefCountedString::TakeString(&out_html)); 116} 117 118} // namespace suggestions 119