#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/search/instant_io_context.h"
#include "chrome/browser/search/search.h"
-#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
-#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/common/url_constants.h"
+#include "components/search_engines/template_url_prepopulate_data.h"
+#include "components/search_engines/template_url_service.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "net/url_request/url_request.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
+#include "ui/base/webui/web_ui_util.h"
#include "url/gurl.h"
namespace {
+// Constants related to the Material Design NTP field trial.
+const char kMaterialDesignNTPFieldTrialName[] = "MaterialDesignNTP";
+const char kMaterialDesignNTPFieldTrialEnabledPrefix[] = "Enabled";
+
+// Names of NTP designs in local resources, also used in CSS.
+const char kClassicalNTPName[] = "classical";
+const char kMaterialDesignNTPName[] = "md";
+
// Signifies a locally constructed resource, i.e. not from grit/.
const int kLocalResource = -1;
const char kConfigDataFilename[] = "config.js";
+const char kLocalNTPFilename[] = "local-ntp.html";
const struct Resource{
const char* filename;
int identifier;
const char* mime_type;
} kResources[] = {
- { "local-ntp.html", IDR_LOCAL_NTP_HTML, "text/html" },
+ { kLocalNTPFilename, IDR_LOCAL_NTP_HTML, "text/html" },
{ "local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript" },
{ kConfigDataFilename, kLocalResource, "application/javascript" },
{ "local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css" },
{ "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" },
{ "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" },
{ "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" },
- { "images/2x/google_logo.png",
- IDR_LOCAL_NTP_IMAGES_2X_LOGO_PNG, "image/png" },
- { "images/2x/white_google_logo.png",
- IDR_LOCAL_NTP_IMAGES_2X_WHITE_LOGO_PNG, "image/png" },
+ { "images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png" },
+ { "images/google_logo.png", IDR_LOCAL_NTP_IMAGES_LOGO_PNG, "image/png" },
+ { "images/white_google_logo.png",
+ IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG, "image/png" },
+ { "images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png" },
};
// Strips any query parameters from the specified path.
const TemplateURL* default_provider =
template_url_service->GetDefaultSearchProvider();
return default_provider &&
- (TemplateURLPrepopulateData::GetEngineType(*default_provider) ==
+ (TemplateURLPrepopulateData::GetEngineType(
+ *default_provider, template_url_service->search_terms_data()) ==
SEARCH_ENGINE_GOOGLE);
}
+// Returns whether the user is part of a group where the Material Design NTP is
+// enabled.
+bool IsMaterialDesignEnabled() {
+ return StartsWithASCII(
+ base::FieldTrialList::FindFullName(kMaterialDesignNTPFieldTrialName),
+ kMaterialDesignNTPFieldTrialEnabledPrefix, true);
+}
+
// Adds a localized string keyed by resource id to the dictionary.
void AddString(base::DictionaryValue* dictionary,
const std::string& key,
dictionary->SetString(key, l10n_util::GetStringUTF16(resource_id));
}
-// Populates |translated_strings| dictionary for the local NTP.
-scoped_ptr<base::DictionaryValue> GetTranslatedStrings() {
+// Adds a localized string for the Google searchbox placeholder text.
+void AddGoogleSearchboxPlaceholderString(base::DictionaryValue* dictionary) {
+ base::string16 placeholder = l10n_util::GetStringFUTF16(
+ IDS_OMNIBOX_EMPTY_HINT_WITH_DEFAULT_SEARCH_PROVIDER,
+ base::ASCIIToUTF16("Google"));
+ dictionary->SetString("searchboxPlaceholder", placeholder);
+}
+
+// Populates |translated_strings| dictionary for the local NTP. |is_google|
+// indicates that this page is the Google Local NTP.
+scoped_ptr<base::DictionaryValue> GetTranslatedStrings(bool is_google) {
scoped_ptr<base::DictionaryValue> translated_strings(
new base::DictionaryValue());
AddString(translated_strings.get(), "attributionIntro",
IDS_NEW_TAB_ATTRIBUTION_INTRO);
AddString(translated_strings.get(), "title", IDS_NEW_TAB_TITLE);
+ if (is_google)
+ AddGoogleSearchboxPlaceholderString(translated_strings.get());
return translated_strings.Pass();
}
// Returns a JS dictionary of configuration data for the local NTP.
std::string GetConfigData(Profile* profile) {
base::DictionaryValue config_data;
- config_data.Set("translatedStrings", GetTranslatedStrings().release());
- config_data.SetBoolean("isGooglePage",
- DefaultSearchProviderIsGoogle(profile));
+ bool is_google = DefaultSearchProviderIsGoogle(profile) &&
+ chrome::ShouldShowGoogleLocalNTP();
+ config_data.Set("translatedStrings",
+ GetTranslatedStrings(is_google).release());
+ config_data.SetBoolean("isGooglePage", is_google);
+ if (IsMaterialDesignEnabled()) {
+ scoped_ptr<base::Value> design_value(
+ new base::StringValue(kMaterialDesignNTPName));
+ config_data.Set("ntpDesignName", design_value.release());
+ }
// Serialize the dictionary.
std::string js_text;
return config_data_js;
}
+std::string GetLocalNtpPath() {
+ return std::string(chrome::kChromeSearchScheme) + "://" +
+ std::string(chrome::kChromeSearchLocalNtpHost) + "/";
+}
+
} // namespace
LocalNtpSource::LocalNtpSource(Profile* profile) : profile_(profile) {
callback.Run(base::RefCountedString::TakeString(&config_data_js));
return;
}
+ if (stripped_path == kLocalNTPFilename) {
+ SendResourceWithClass(
+ IDR_LOCAL_NTP_HTML,
+ IsMaterialDesignEnabled() ? kMaterialDesignNTPName : kClassicalNTPName,
+ callback);
+ return;
+ }
+ float scale = 1.0f;
+ std::string filename;
+ webui::ParsePathAndScale(
+ GURL(GetLocalNtpPath() + stripped_path), &filename, &scale);
+ ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale);
for (size_t i = 0; i < arraysize(kResources); ++i) {
- if (stripped_path == kResources[i].filename) {
+ if (filename == kResources[i].filename) {
scoped_refptr<base::RefCountedStaticMemory> response(
- ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
- kResources[i].identifier));
+ ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
+ kResources[i].identifier, scale_factor));
callback.Run(response.get());
return;
}
}
callback.Run(NULL);
-};
+}
std::string LocalNtpSource::GetMimeType(
const std::string& path) const {
return false;
if (request->url().SchemeIs(chrome::kChromeSearchScheme)) {
- DCHECK(StartsWithASCII(request->url().path(), "/", true));
- std::string filename = request->url().path().substr(1);
+ std::string filename;
+ webui::ParsePathAndScale(request->url(), &filename, NULL);
for (size_t i = 0; i < arraysize(kResources); ++i) {
if (filename == kResources[i].filename)
return true;
return base::StringPrintf("frame-src %s;",
chrome::kChromeSearchMostVisitedUrl);
}
+
+void LocalNtpSource::SendResourceWithClass(
+ int resource_id,
+ const std::string& class_name,
+ const content::URLDataSource::GotDataCallback& callback) {
+ base::StringPiece resource_data =
+ ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
+ std::string response(resource_data.as_string());
+ ReplaceFirstSubstringAfterOffset(&response, 0, "{{CLASS}}", class_name);
+ callback.Run(base::RefCountedString::TakeString(&response));
+}