1 // Copyright (c) 2011 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/ui/webui/ntp_resource_cache.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/command_line.h"
11 #include "base/file_util.h"
12 #include "base/memory/ref_counted_memory.h"
13 #include "base/string16.h"
14 #include "base/string_number_conversions.h"
15 #include "base/time.h"
16 #include "base/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/google/google_util.h"
19 #include "chrome/browser/metrics/user_metrics.h"
20 #include "chrome/browser/prefs/pref_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/themes/theme_service.h"
23 #include "chrome/browser/themes/theme_service_factory.h"
24 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
25 #include "chrome/browser/ui/webui/shown_sections_handler.h"
26 #include "chrome/browser/web_resource/promo_resource_service.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/extensions/extension.h"
29 #include "chrome/common/extensions/extension_constants.h"
30 #include "chrome/common/jstemplate_builder.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "content/browser/browser_thread.h"
34 #include "content/common/notification_service.h"
35 #include "content/common/notification_type.h"
36 #include "grit/browser_resources.h"
37 #include "grit/chromium_strings.h"
38 #include "grit/generated_resources.h"
39 #include "grit/locale_settings.h"
40 #include "grit/theme_resources.h"
41 #include "ui/base/animation/animation.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/base/resource/resource_bundle.h"
44 #include "ui/base/theme_provider.h"
45 #include "ui/gfx/color_utils.h"
46
47 #if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
48 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
49 #elif defined(OS_MACOSX)
50 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
51 #elif defined(OS_POSIX)
52 #include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h"
53 #endif
54
55 using base::Time;
56
57 namespace {
58
59 // The URL for the the Learn More page shown on incognito new tab.
60 const char kLearnMoreIncognitoUrl[] =
61 #if defined(OS_CHROMEOS)
62 "https://www.google.com/support/chromeos/bin/answer.py?answer=95464";
63 #else
64 "https://www.google.com/support/chrome/bin/answer.py?answer=95464";
65 #endif
66
67 // The URL for the Learn More page shown on guest session new tab.
68 const char kLearnMoreGuestSessionUrl[] =
69 "https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
70
71 // The URL for bookmark sync service help.
72 const char kSyncServiceHelpUrl[] =
73 "https://www.google.com/support/chrome/bin/answer.py?answer=165139";
74
75 // The URL to be loaded to display Help.
76 const char kHelpContentUrl[] =
77 "https://www.google.com/support/chrome/";
78
GetUrlWithLang(const GURL & url)79 string16 GetUrlWithLang(const GURL& url) {
80 return ASCIIToUTF16(google_util::AppendGoogleLocaleParam(url).spec());
81 }
82
SkColorToRGBAString(SkColor color)83 std::string SkColorToRGBAString(SkColor color) {
84 // We convert the alpha using DoubleToString because StringPrintf will use
85 // locale specific formatters (e.g., use , instead of . in German).
86 return StringPrintf("rgba(%d,%d,%d,%s)", SkColorGetR(color),
87 SkColorGetG(color), SkColorGetB(color),
88 base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
89 }
90
91 // Get the CSS string for the background position on the new tab page for the
92 // states when the bar is attached or detached.
GetNewTabBackgroundCSS(const ui::ThemeProvider * theme_provider,bool bar_attached)93 std::string GetNewTabBackgroundCSS(const ui::ThemeProvider* theme_provider,
94 bool bar_attached) {
95 int alignment;
96 theme_provider->GetDisplayProperty(
97 ThemeService::NTP_BACKGROUND_ALIGNMENT, &alignment);
98
99 // TODO(glen): This is a quick workaround to hide the notused.png image when
100 // no image is provided - we don't have time right now to figure out why
101 // this is painting as white.
102 // http://crbug.com/17593
103 if (!theme_provider->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
104 return "-64px";
105 }
106
107 if (bar_attached)
108 return ThemeService::AlignmentToString(alignment);
109
110 // The bar is detached, so we must offset the background by the bar size
111 // if it's a top-aligned bar.
112 #if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
113 int offset = BookmarkBarView::kNewtabBarHeight;
114 #elif defined(OS_MACOSX)
115 int offset = bookmarks::kNTPBookmarkBarHeight;
116 #elif defined(OS_POSIX)
117 int offset = BookmarkBarGtk::kBookmarkBarNTPHeight;
118 #else
119 int offset = 0;
120 #endif
121
122 if (alignment & ThemeService::ALIGN_TOP) {
123 if (alignment & ThemeService::ALIGN_LEFT)
124 return "0% " + base::IntToString(-offset) + "px";
125 else if (alignment & ThemeService::ALIGN_RIGHT)
126 return "100% " + base::IntToString(-offset) + "px";
127 return "center " + base::IntToString(-offset) + "px";
128 }
129 return ThemeService::AlignmentToString(alignment);
130 }
131
132 // How the background image on the new tab page should be tiled (see tiling
133 // masks in theme_service.h).
GetNewTabBackgroundTilingCSS(const ui::ThemeProvider * theme_provider)134 std::string GetNewTabBackgroundTilingCSS(
135 const ui::ThemeProvider* theme_provider) {
136 int repeat_mode;
137 theme_provider->GetDisplayProperty(
138 ThemeService::NTP_BACKGROUND_TILING, &repeat_mode);
139 return ThemeService::TilingToString(repeat_mode);
140 }
141
142 // Is the current time within a given date range?
InDateRange(double begin,double end)143 bool InDateRange(double begin, double end) {
144 Time start_time = Time::FromDoubleT(begin);
145 Time end_time = Time::FromDoubleT(end);
146 return start_time < Time::Now() && end_time > Time::Now();
147 }
148
149 } // namespace
150
NTPResourceCache(Profile * profile)151 NTPResourceCache::NTPResourceCache(Profile* profile) : profile_(profile) {
152 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
153 NotificationService::AllSources());
154 registrar_.Add(this, NotificationType::PROMO_RESOURCE_STATE_CHANGED,
155 NotificationService::AllSources());
156
157 // Watch for pref changes that cause us to need to invalidate the HTML cache.
158 pref_change_registrar_.Init(profile_->GetPrefs());
159 pref_change_registrar_.Add(prefs::kShowBookmarkBar, this);
160 pref_change_registrar_.Add(prefs::kEnableBookmarkBar, this);
161 pref_change_registrar_.Add(prefs::kNTPShownSections, this);
162 }
163
~NTPResourceCache()164 NTPResourceCache::~NTPResourceCache() {}
165
GetNewTabHTML(bool is_incognito)166 RefCountedBytes* NTPResourceCache::GetNewTabHTML(bool is_incognito) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 if (is_incognito) {
169 if (!new_tab_incognito_html_.get())
170 CreateNewTabIncognitoHTML();
171 } else {
172 if (!new_tab_html_.get())
173 CreateNewTabHTML();
174 }
175 return is_incognito ? new_tab_incognito_html_.get()
176 : new_tab_html_.get();
177 }
178
GetNewTabCSS(bool is_incognito)179 RefCountedBytes* NTPResourceCache::GetNewTabCSS(bool is_incognito) {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181 if (is_incognito) {
182 if (!new_tab_incognito_css_.get())
183 CreateNewTabIncognitoCSS();
184 } else {
185 if (!new_tab_css_.get())
186 CreateNewTabCSS();
187 }
188 return is_incognito ? new_tab_incognito_css_.get()
189 : new_tab_css_.get();
190 }
191
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)192 void NTPResourceCache::Observe(NotificationType type,
193 const NotificationSource& source, const NotificationDetails& details) {
194 // Invalidate the cache.
195 if (NotificationType::BROWSER_THEME_CHANGED == type ||
196 NotificationType::PROMO_RESOURCE_STATE_CHANGED == type) {
197 new_tab_incognito_html_ = NULL;
198 new_tab_html_ = NULL;
199 new_tab_incognito_css_ = NULL;
200 new_tab_css_ = NULL;
201 } else if (NotificationType::PREF_CHANGED == type) {
202 std::string* pref_name = Details<std::string>(details).ptr();
203 if (*pref_name == prefs::kShowBookmarkBar ||
204 *pref_name == prefs::kEnableBookmarkBar ||
205 *pref_name == prefs::kHomePageIsNewTabPage ||
206 *pref_name == prefs::kNTPShownSections) {
207 new_tab_incognito_html_ = NULL;
208 new_tab_html_ = NULL;
209 } else {
210 NOTREACHED();
211 }
212 } else {
213 NOTREACHED();
214 }
215 }
216
CreateNewTabIncognitoHTML()217 void NTPResourceCache::CreateNewTabIncognitoHTML() {
218 DictionaryValue localized_strings;
219 localized_strings.SetString("title",
220 l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
221 int new_tab_message_ids = IDS_NEW_TAB_OTR_MESSAGE;
222 int new_tab_html_idr = IDR_INCOGNITO_TAB_HTML;
223 const char* new_tab_link = kLearnMoreIncognitoUrl;
224 // TODO(altimofeev): consider implementation without 'if def' usage.
225 #if defined(OS_CHROMEOS)
226 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) {
227 new_tab_message_ids = IDS_NEW_TAB_GUEST_SESSION_MESSAGE;
228 new_tab_html_idr = IDR_GUEST_SESSION_TAB_HTML;
229 new_tab_link = kLearnMoreGuestSessionUrl;
230 }
231 #endif
232 localized_strings.SetString("content",
233 l10n_util::GetStringFUTF16(new_tab_message_ids,
234 GetUrlWithLang(GURL(new_tab_link))));
235 localized_strings.SetString("extensionsmessage",
236 l10n_util::GetStringFUTF16(IDS_NEW_TAB_OTR_EXTENSIONS_MESSAGE,
237 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
238 ASCIIToUTF16(chrome::kChromeUIExtensionsURL)));
239 bool bookmark_bar_attached = profile_->GetPrefs()->GetBoolean(
240 prefs::kShowBookmarkBar);
241 localized_strings.SetString("bookmarkbarattached",
242 bookmark_bar_attached ? "true" : "false");
243
244 ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
245
246 static const base::StringPiece incognito_tab_html(
247 ResourceBundle::GetSharedInstance().GetRawDataResource(
248 new_tab_html_idr));
249
250 std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
251 incognito_tab_html, &localized_strings);
252
253 new_tab_incognito_html_ = new RefCountedBytes;
254 new_tab_incognito_html_->data.resize(full_html.size());
255 std::copy(full_html.begin(), full_html.end(),
256 new_tab_incognito_html_->data.begin());
257 }
258
CreateNewTabHTML()259 void NTPResourceCache::CreateNewTabHTML() {
260 // Show the profile name in the title and most visited labels if the current
261 // profile is not the default.
262 string16 apps = l10n_util::GetStringUTF16(IDS_NEW_TAB_APPS);
263 string16 title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
264 string16 most_visited = l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED);
265 DictionaryValue localized_strings;
266 localized_strings.SetString("bookmarkbarattached",
267 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) ?
268 "true" : "false");
269 localized_strings.SetString("hasattribution",
270 ThemeServiceFactory::GetForProfile(profile_)->HasCustomImage(
271 IDR_THEME_NTP_ATTRIBUTION) ?
272 "true" : "false");
273 localized_strings.SetString("apps", apps);
274 localized_strings.SetString("title", title);
275 localized_strings.SetString("mostvisited", most_visited);
276 localized_strings.SetString("restorethumbnails",
277 l10n_util::GetStringUTF16(IDS_NEW_TAB_RESTORE_THUMBNAILS_LINK));
278 localized_strings.SetString("recentlyclosed",
279 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED));
280 localized_strings.SetString("closedwindowsingle",
281 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE));
282 localized_strings.SetString("foreignsessions",
283 l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_SESSIONS));
284 localized_strings.SetString("closedwindowmultiple",
285 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE));
286 localized_strings.SetString("attributionintro",
287 l10n_util::GetStringUTF16(IDS_NEW_TAB_ATTRIBUTION_INTRO));
288 localized_strings.SetString("thumbnailremovednotification",
289 l10n_util::GetStringUTF16(IDS_NEW_TAB_THUMBNAIL_REMOVED_NOTIFICATION));
290 localized_strings.SetString("undothumbnailremove",
291 l10n_util::GetStringUTF16(IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE));
292 localized_strings.SetString("removethumbnailtooltip",
293 l10n_util::GetStringUTF16(IDS_NEW_TAB_REMOVE_THUMBNAIL_TOOLTIP));
294 localized_strings.SetString("pinthumbnailtooltip",
295 l10n_util::GetStringUTF16(IDS_NEW_TAB_PIN_THUMBNAIL_TOOLTIP));
296 localized_strings.SetString("unpinthumbnailtooltip",
297 l10n_util::GetStringUTF16(IDS_NEW_TAB_UNPIN_THUMBNAIL_TOOLTIP));
298 localized_strings.SetString("showhidethumbnailtooltip",
299 l10n_util::GetStringUTF16(IDS_NEW_TAB_SHOW_HIDE_THUMBNAIL_TOOLTIP));
300 localized_strings.SetString("showhidelisttooltip",
301 l10n_util::GetStringUTF16(IDS_NEW_TAB_SHOW_HIDE_LIST_TOOLTIP));
302 localized_strings.SetString("pagedisplaytooltip",
303 l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_DISPLAY_TOOLTIP));
304 localized_strings.SetString("closefirstrunnotification",
305 l10n_util::GetStringUTF16(IDS_NEW_TAB_CLOSE_FIRST_RUN_NOTIFICATION));
306 localized_strings.SetString("close", l10n_util::GetStringUTF16(IDS_CLOSE));
307 localized_strings.SetString("history",
308 l10n_util::GetStringUTF16(IDS_NEW_TAB_HISTORY));
309 localized_strings.SetString("downloads",
310 l10n_util::GetStringUTF16(IDS_NEW_TAB_DOWNLOADS));
311 localized_strings.SetString("help",
312 l10n_util::GetStringUTF16(IDS_NEW_TAB_HELP));
313 localized_strings.SetString("helpurl",
314 GetUrlWithLang(GURL(kHelpContentUrl)));
315 localized_strings.SetString("appsettings",
316 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_SETTINGS));
317 localized_strings.SetString("appuninstall",
318 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_UNINSTALL));
319 localized_strings.SetString("appoptions",
320 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_OPTIONS));
321 localized_strings.SetString("appcreateshortcut",
322 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_CREATE_SHORTCUT));
323 localized_strings.SetString("applaunchtypepinned",
324 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
325 localized_strings.SetString("applaunchtyperegular",
326 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
327 localized_strings.SetString("applaunchtypewindow",
328 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
329 localized_strings.SetString("applaunchtypefullscreen",
330 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
331 localized_strings.SetString("web_store_title",
332 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
333 localized_strings.SetString("web_store_url",
334 GetUrlWithLang(GURL(Extension::ChromeStoreLaunchURL())));
335 localized_strings.SetString("syncpromotext",
336 l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL));
337 #if defined(OS_CHROMEOS)
338 localized_strings.SetString("expandMenu",
339 l10n_util::GetStringUTF16(IDS_NEW_TAB_CLOSE_MENU_EXPAND));
340 #endif
341
342 // Don't initiate the sync related message passing with the page if the sync
343 // code is not present.
344 if (profile_->GetProfileSyncService())
345 localized_strings.SetString("syncispresent", "true");
346 else
347 localized_strings.SetString("syncispresent", "false");
348
349 ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
350
351 // Control fade and resize animations.
352 std::string anim =
353 ui::Animation::ShouldRenderRichAnimation() ? "true" : "false";
354 localized_strings.SetString("anim", anim);
355
356 // Pass the shown_sections pref early so that we can prevent flicker.
357 const int shown_sections = ShownSectionsHandler::GetShownSections(
358 profile_->GetPrefs());
359 localized_strings.SetInteger("shown_sections", shown_sections);
360
361 // If the user has preferences for a start and end time for a custom logo,
362 // and the time now is between these two times, show the custom logo.
363 if (profile_->GetPrefs()->FindPreference(prefs::kNTPCustomLogoStart) &&
364 profile_->GetPrefs()->FindPreference(prefs::kNTPCustomLogoEnd)) {
365 localized_strings.SetString("customlogo",
366 InDateRange(profile_->GetPrefs()->GetDouble(prefs::kNTPCustomLogoStart),
367 profile_->GetPrefs()->GetDouble(prefs::kNTPCustomLogoEnd)) ?
368 "true" : "false");
369 } else {
370 localized_strings.SetString("customlogo", "false");
371 }
372
373 // If the user has preferences for a start and end time for a promo from
374 // the server, and this promo string exists, set the localized string.
375 if (profile_->GetPrefs()->FindPreference(prefs::kNTPPromoStart) &&
376 profile_->GetPrefs()->FindPreference(prefs::kNTPPromoEnd) &&
377 profile_->GetPrefs()->FindPreference(prefs::kNTPPromoLine) &&
378 PromoResourceServiceUtil::CanShowPromo(profile_)) {
379 localized_strings.SetString("serverpromo",
380 InDateRange(profile_->GetPrefs()->GetDouble(prefs::kNTPPromoStart),
381 profile_->GetPrefs()->GetDouble(prefs::kNTPPromoEnd)) ?
382 profile_->GetPrefs()->GetString(prefs::kNTPPromoLine) :
383 std::string());
384 UserMetrics::RecordAction(UserMetricsAction("NTPPromoShown"));
385 }
386
387 // Load the new tab page appropriate for this build
388 // Note that some builds (eg. TOUCHUI) don't make use of everything we
389 // do here (all of the template data, etc.), but we keep the back end
390 // consistent across builds, supporting the union of all NTP front-ends
391 // for simplicity.
392 std::string full_html;
393 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) {
394 base::StringPiece new_tab_html(ResourceBundle::GetSharedInstance().
395 GetRawDataResource(IDR_NEW_TAB_4_HTML));
396 full_html = jstemplate_builder::GetI18nTemplateHtml(new_tab_html,
397 &localized_strings);
398 } else {
399 base::StringPiece new_tab_html(ResourceBundle::GetSharedInstance().
400 GetRawDataResource(IDR_NEW_TAB_HTML));
401
402 // Inject the template data into the HTML so that it is available before any
403 // layout is needed.
404 std::string json_html;
405 jstemplate_builder::AppendJsonHtml(&localized_strings, &json_html);
406
407 static const base::StringPiece template_data_placeholder(
408 "<!-- template data placeholder -->");
409 size_t pos = new_tab_html.find(template_data_placeholder);
410
411 if (pos != base::StringPiece::npos) {
412 full_html.assign(new_tab_html.data(), pos);
413 full_html.append(json_html);
414 size_t after_offset = pos + template_data_placeholder.size();
415 full_html.append(new_tab_html.data() + after_offset,
416 new_tab_html.size() - after_offset);
417 } else {
418 NOTREACHED();
419 full_html.assign(new_tab_html.data(), new_tab_html.size());
420 }
421 }
422
423 new_tab_html_ = new RefCountedBytes;
424 new_tab_html_->data.resize(full_html.size());
425 std::copy(full_html.begin(), full_html.end(), new_tab_html_->data.begin());
426 }
427
CreateNewTabIncognitoCSS()428 void NTPResourceCache::CreateNewTabIncognitoCSS() {
429 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
430 DCHECK(tp);
431
432 // Get our theme colors
433 SkColor color_background =
434 tp->GetColor(ThemeService::COLOR_NTP_BACKGROUND);
435
436 // Generate the replacements.
437 std::vector<std::string> subst;
438
439 // Cache-buster for background.
440 subst.push_back(
441 profile_->GetPrefs()->GetString(prefs::kCurrentThemeID)); // $1
442
443 // Colors.
444 subst.push_back(SkColorToRGBAString(color_background)); // $2
445 subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
446 subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
447 subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
448
449 // Get our template.
450 static const base::StringPiece new_tab_theme_css(
451 ResourceBundle::GetSharedInstance().GetRawDataResource(
452 IDR_NEW_INCOGNITO_TAB_THEME_CSS));
453
454 // Create the string from our template and the replacements.
455 std::string full_css = ReplaceStringPlaceholders(
456 new_tab_theme_css, subst, NULL);
457
458 new_tab_incognito_css_ = new RefCountedBytes;
459 new_tab_incognito_css_->data.resize(full_css.size());
460 std::copy(full_css.begin(), full_css.end(),
461 new_tab_incognito_css_->data.begin());
462 }
463
CreateNewTabCSS()464 void NTPResourceCache::CreateNewTabCSS() {
465 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
466 DCHECK(tp);
467
468 // Get our theme colors
469 SkColor color_background =
470 tp->GetColor(ThemeService::COLOR_NTP_BACKGROUND);
471 SkColor color_text = tp->GetColor(ThemeService::COLOR_NTP_TEXT);
472 SkColor color_link = tp->GetColor(ThemeService::COLOR_NTP_LINK);
473 SkColor color_link_underline =
474 tp->GetColor(ThemeService::COLOR_NTP_LINK_UNDERLINE);
475
476 SkColor color_section =
477 tp->GetColor(ThemeService::COLOR_NTP_SECTION);
478 SkColor color_section_text =
479 tp->GetColor(ThemeService::COLOR_NTP_SECTION_TEXT);
480 SkColor color_section_link =
481 tp->GetColor(ThemeService::COLOR_NTP_SECTION_LINK);
482 SkColor color_section_link_underline =
483 tp->GetColor(ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE);
484 SkColor color_section_header_text =
485 tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_TEXT);
486 SkColor color_section_header_text_hover =
487 tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_TEXT_HOVER);
488 SkColor color_section_header_rule =
489 tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_RULE);
490 SkColor color_section_header_rule_light =
491 tp->GetColor(ThemeService::COLOR_NTP_SECTION_HEADER_RULE_LIGHT);
492 SkColor color_text_light =
493 tp->GetColor(ThemeService::COLOR_NTP_TEXT_LIGHT);
494
495 SkColor color_header =
496 tp->GetColor(ThemeService::COLOR_NTP_HEADER);
497 // Generate a lighter color for the header gradients.
498 color_utils::HSL header_lighter;
499 color_utils::SkColorToHSL(color_header, &header_lighter);
500 header_lighter.l += (1 - header_lighter.l) * 0.33;
501 SkColor color_header_gradient_light =
502 color_utils::HSLToSkColor(header_lighter, SkColorGetA(color_header));
503
504 // Generate section border color from the header color. See
505 // BookmarkBarView::Paint for how we do this for the bookmark bar
506 // borders.
507 SkColor color_section_border =
508 SkColorSetARGB(80,
509 SkColorGetR(color_header),
510 SkColorGetG(color_header),
511 SkColorGetB(color_header));
512
513 // Generate the replacements.
514 std::vector<std::string> subst;
515 // A second list of replacements, each of which must be in $$x format,
516 // where x is a digit from 1-9.
517 std::vector<std::string> subst2;
518 std::vector<std::string> subst3;
519
520 // Cache-buster for background.
521 subst.push_back(
522 profile_->GetPrefs()->GetString(prefs::kCurrentThemeID)); // $1
523
524 // Colors.
525 subst.push_back(SkColorToRGBAString(color_background)); // $2
526 subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
527 subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
528 subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
529 subst.push_back(SkColorToRGBAString(color_header)); // $6
530 subst.push_back(SkColorToRGBAString(color_header_gradient_light)); // $7
531 subst.push_back(SkColorToRGBAString(color_text)); // $8
532 subst.push_back(SkColorToRGBAString(color_link)); // $9
533
534 subst2.push_back(SkColorToRGBAString(color_section)); // $$1
535 subst2.push_back(SkColorToRGBAString(color_section_border)); // $$2
536 subst2.push_back(SkColorToRGBAString(color_section_text)); // $$3
537 subst2.push_back(SkColorToRGBAString(color_section_link)); // $$4
538 subst2.push_back(SkColorToRGBAString(color_link_underline)); // $$5
539 subst2.push_back(SkColorToRGBAString(color_section_link_underline)); // $$6
540 subst2.push_back(SkColorToRGBAString(color_section_header_text)); // $$7
541 subst2.push_back(SkColorToRGBAString(
542 color_section_header_text_hover)); // $$8
543 subst2.push_back(SkColorToRGBAString(color_section_header_rule)); // $$9
544
545 subst3.push_back(SkColorToRGBAString(
546 color_section_header_rule_light)); // $$$1
547 subst3.push_back(SkColorToRGBAString(
548 SkColorSetA(color_section_header_rule, 0))); // $$$2
549 subst3.push_back(SkColorToRGBAString(color_text_light)); // $$$3
550
551 // Get our template.
552 int ntp_css_resource_id =
553 CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4) ?
554 IDR_NEW_TAB_4_THEME_CSS : IDR_NEW_TAB_THEME_CSS;
555 static const base::StringPiece new_tab_theme_css(
556 ResourceBundle::GetSharedInstance().GetRawDataResource(
557 ntp_css_resource_id));
558
559 // Create the string from our template and the replacements.
560 std::string css_string;
561 css_string = ReplaceStringPlaceholders(new_tab_theme_css, subst, NULL);
562 css_string = ReplaceStringPlaceholders(css_string, subst2, NULL);
563 css_string = ReplaceStringPlaceholders(css_string, subst3, NULL);
564
565 new_tab_css_ = new RefCountedBytes;
566 new_tab_css_->data.resize(css_string.size());
567 std::copy(css_string.begin(), css_string.end(),
568 new_tab_css_->data.begin());
569 }
570