Home | History | Annotate | Download | only in search
      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 "chrome/browser/search/local_ntp_source.h"
      6 
      7 #include "base/json/json_string_value_serializer.h"
      8 #include "base/logging.h"
      9 #include "base/memory/ref_counted_memory.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/values.h"
     14 #include "chrome/browser/search/instant_io_context.h"
     15 #include "chrome/browser/search/search.h"
     16 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
     17 #include "chrome/browser/search_engines/template_url_service.h"
     18 #include "chrome/browser/search_engines/template_url_service_factory.h"
     19 #include "chrome/common/url_constants.h"
     20 #include "grit/browser_resources.h"
     21 #include "grit/generated_resources.h"
     22 #include "grit/theme_resources.h"
     23 #include "grit/ui_resources.h"
     24 #include "net/url_request/url_request.h"
     25 #include "ui/base/l10n/l10n_util.h"
     26 #include "ui/base/resource/resource_bundle.h"
     27 #include "ui/base/webui/jstemplate_builder.h"
     28 #include "ui/base/webui/web_ui_util.h"
     29 #include "url/gurl.h"
     30 
     31 namespace {
     32 
     33 // Signifies a locally constructed resource, i.e. not from grit/.
     34 const int kLocalResource = -1;
     35 
     36 const char kConfigDataFilename[] = "config.js";
     37 
     38 const struct Resource{
     39   const char* filename;
     40   int identifier;
     41   const char* mime_type;
     42 } kResources[] = {
     43   { "local-ntp.html", IDR_LOCAL_NTP_HTML, "text/html" },
     44   { "local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript" },
     45   { kConfigDataFilename, kLocalResource, "application/javascript" },
     46   { "local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css" },
     47   { "images/close_2.png", IDR_CLOSE_2, "image/png" },
     48   { "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" },
     49   { "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" },
     50   { "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" },
     51   { "images/google_logo.png", IDR_LOCAL_NTP_IMAGES_LOGO_PNG, "image/png" },
     52   { "images/white_google_logo.png",
     53     IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG, "image/png" },
     54 };
     55 
     56 // Strips any query parameters from the specified path.
     57 std::string StripParameters(const std::string& path) {
     58   return path.substr(0, path.find("?"));
     59 }
     60 
     61 bool DefaultSearchProviderIsGoogle(Profile* profile) {
     62   if (!profile)
     63     return false;
     64 
     65   TemplateURLService* template_url_service =
     66       TemplateURLServiceFactory::GetForProfile(profile);
     67   if (!template_url_service)
     68     return false;
     69 
     70   const TemplateURL* default_provider =
     71       template_url_service->GetDefaultSearchProvider();
     72   return default_provider &&
     73       (TemplateURLPrepopulateData::GetEngineType(
     74           *default_provider, template_url_service->search_terms_data()) ==
     75        SEARCH_ENGINE_GOOGLE);
     76 }
     77 
     78 // Adds a localized string keyed by resource id to the dictionary.
     79 void AddString(base::DictionaryValue* dictionary,
     80                const std::string& key,
     81                int resource_id) {
     82   dictionary->SetString(key, l10n_util::GetStringUTF16(resource_id));
     83 }
     84 
     85 // Populates |translated_strings| dictionary for the local NTP.
     86 scoped_ptr<base::DictionaryValue> GetTranslatedStrings() {
     87   scoped_ptr<base::DictionaryValue> translated_strings(
     88       new base::DictionaryValue());
     89 
     90   AddString(translated_strings.get(), "thumbnailRemovedNotification",
     91             IDS_NEW_TAB_THUMBNAIL_REMOVED_NOTIFICATION);
     92   AddString(translated_strings.get(), "removeThumbnailTooltip",
     93             IDS_NEW_TAB_REMOVE_THUMBNAIL_TOOLTIP);
     94   AddString(translated_strings.get(), "undoThumbnailRemove",
     95             IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE);
     96   AddString(translated_strings.get(), "restoreThumbnailsShort",
     97             IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK);
     98   AddString(translated_strings.get(), "attributionIntro",
     99             IDS_NEW_TAB_ATTRIBUTION_INTRO);
    100   AddString(translated_strings.get(), "title", IDS_NEW_TAB_TITLE);
    101 
    102   return translated_strings.Pass();
    103 }
    104 
    105 // Returns a JS dictionary of configuration data for the local NTP.
    106 std::string GetConfigData(Profile* profile) {
    107   base::DictionaryValue config_data;
    108   config_data.Set("translatedStrings", GetTranslatedStrings().release());
    109   config_data.SetBoolean("isGooglePage",
    110                          DefaultSearchProviderIsGoogle(profile) &&
    111                          chrome::ShouldShowGoogleLocalNTP());
    112 
    113   // Serialize the dictionary.
    114   std::string js_text;
    115   JSONStringValueSerializer serializer(&js_text);
    116   serializer.Serialize(config_data);
    117 
    118   std::string config_data_js;
    119   config_data_js.append("var configData = ");
    120   config_data_js.append(js_text);
    121   config_data_js.append(";");
    122   return config_data_js;
    123 }
    124 
    125 std::string GetLocalNtpPath() {
    126   return std::string(chrome::kChromeSearchScheme) + "://" +
    127          std::string(chrome::kChromeSearchLocalNtpHost) + "/";
    128 }
    129 
    130 }  // namespace
    131 
    132 LocalNtpSource::LocalNtpSource(Profile* profile) : profile_(profile) {
    133 }
    134 
    135 LocalNtpSource::~LocalNtpSource() {
    136 }
    137 
    138 std::string LocalNtpSource::GetSource() const {
    139   return chrome::kChromeSearchLocalNtpHost;
    140 }
    141 
    142 void LocalNtpSource::StartDataRequest(
    143     const std::string& path,
    144     int render_process_id,
    145     int render_frame_id,
    146     const content::URLDataSource::GotDataCallback& callback) {
    147   const std::string stripped_path = StripParameters(path);
    148   if (stripped_path == kConfigDataFilename) {
    149     std::string config_data_js = GetConfigData(profile_);
    150     callback.Run(base::RefCountedString::TakeString(&config_data_js));
    151     return;
    152   }
    153   float scale = 1.0f;
    154   std::string filename;
    155   webui::ParsePathAndScale(
    156       GURL(GetLocalNtpPath() + stripped_path), &filename, &scale);
    157   ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale);
    158   for (size_t i = 0; i < arraysize(kResources); ++i) {
    159     if (filename == kResources[i].filename) {
    160       scoped_refptr<base::RefCountedStaticMemory> response(
    161           ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
    162               kResources[i].identifier, scale_factor));
    163       callback.Run(response.get());
    164       return;
    165     }
    166   }
    167   callback.Run(NULL);
    168 }
    169 
    170 std::string LocalNtpSource::GetMimeType(
    171     const std::string& path) const {
    172   const std::string stripped_path = StripParameters(path);
    173   for (size_t i = 0; i < arraysize(kResources); ++i) {
    174     if (stripped_path == kResources[i].filename)
    175       return kResources[i].mime_type;
    176   }
    177   return std::string();
    178 }
    179 
    180 bool LocalNtpSource::ShouldServiceRequest(
    181     const net::URLRequest* request) const {
    182   DCHECK(request->url().host() == chrome::kChromeSearchLocalNtpHost);
    183   if (!InstantIOContext::ShouldServiceRequest(request))
    184     return false;
    185 
    186   if (request->url().SchemeIs(chrome::kChromeSearchScheme)) {
    187     std::string filename;
    188     webui::ParsePathAndScale(request->url(), &filename, NULL);
    189     for (size_t i = 0; i < arraysize(kResources); ++i) {
    190       if (filename == kResources[i].filename)
    191         return true;
    192     }
    193   }
    194   return false;
    195 }
    196 
    197 std::string LocalNtpSource::GetContentSecurityPolicyFrameSrc() const {
    198   // Allow embedding of most visited iframes.
    199   return base::StringPrintf("frame-src %s;",
    200                             chrome::kChromeSearchMostVisitedUrl);
    201 }
    202