1 // Copyright (c) 2012 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/ntp_resource_cache.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/command_line.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/first_run/first_run.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/search/search.h"
23 #include "chrome/browser/sync/profile_sync_service.h"
24 #include "chrome/browser/sync/profile_sync_service_factory.h"
25 #include "chrome/browser/themes/theme_properties.h"
26 #include "chrome/browser/themes/theme_service.h"
27 #include "chrome/browser/themes/theme_service_factory.h"
28 #include "chrome/browser/ui/app_list/app_list_util.h"
29 #include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h"
30 #include "chrome/browser/ui/sync/sync_promo_ui.h"
31 #include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
32 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
33 #include "chrome/browser/ui/webui/ntp/ntp_login_handler.h"
34 #include "chrome/browser/ui/webui/sync_setup_handler.h"
35 #include "chrome/browser/web_resource/notification_promo.h"
36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/extensions/extension_constants.h"
38 #include "chrome/common/pref_names.h"
39 #include "chrome/common/url_constants.h"
40 #include "components/google/core/browser/google_util.h"
41 #include "content/public/browser/browser_thread.h"
42 #include "content/public/browser/notification_service.h"
43 #include "content/public/browser/render_process_host.h"
44 #include "extensions/common/extension.h"
45 #include "grit/browser_resources.h"
46 #include "grit/chromium_strings.h"
47 #include "grit/generated_resources.h"
48 #include "grit/locale_settings.h"
49 #include "grit/theme_resources.h"
50 #include "ui/base/l10n/l10n_util.h"
51 #include "ui/base/resource/resource_bundle.h"
52 #include "ui/base/theme_provider.h"
53 #include "ui/base/webui/jstemplate_builder.h"
54 #include "ui/base/webui/web_ui_util.h"
55 #include "ui/gfx/animation/animation.h"
56 #include "ui/gfx/color_utils.h"
57 #include "ui/gfx/sys_color_change_listener.h"
58
59 #if defined(OS_CHROMEOS)
60 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
61 #include "chromeos/chromeos_switches.h"
62 #endif
63
64 #if defined(OS_MACOSX)
65 #include "chrome/browser/platform_util.h"
66 #endif
67
68 using content::BrowserThread;
69
70 namespace {
71
72 // The URL for the the Learn More page shown on incognito new tab.
73 const char kLearnMoreIncognitoUrl[] =
74 #if defined(OS_CHROMEOS)
75 "https://www.google.com/support/chromeos/bin/answer.py?answer=95464";
76 #else
77 "https://www.google.com/support/chrome/bin/answer.py?answer=95464";
78 #endif
79
80 // The URL for the Learn More page shown on guest session new tab.
81 const char kLearnMoreGuestSessionUrl[] =
82 "https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
83
SkColorToRGBAString(SkColor color)84 std::string SkColorToRGBAString(SkColor color) {
85 // We convert the alpha using DoubleToString because StringPrintf will use
86 // locale specific formatters (e.g., use , instead of . in German).
87 return base::StringPrintf(
88 "rgba(%d,%d,%d,%s)",
89 SkColorGetR(color),
90 SkColorGetG(color),
91 SkColorGetB(color),
92 base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
93 }
94
95 // Creates an rgb string for an SkColor, but leaves the alpha blank so that the
96 // css can fill it in.
SkColorToRGBComponents(SkColor color)97 std::string SkColorToRGBComponents(SkColor color) {
98 return base::StringPrintf(
99 "%d,%d,%d",
100 SkColorGetR(color),
101 SkColorGetG(color),
102 SkColorGetB(color));
103 }
104
GetThemeColor(ui::ThemeProvider * tp,int id)105 SkColor GetThemeColor(ui::ThemeProvider* tp, int id) {
106 SkColor color = tp->GetColor(id);
107 // If web contents are being inverted because the system is in high-contrast
108 // mode, any system theme colors we use must be inverted too to cancel out.
109 return gfx::IsInvertedColorScheme() ?
110 color_utils::InvertColor(color) : color;
111 }
112
113 // Get the CSS string for the background position on the new tab page for the
114 // states when the bar is attached or detached.
GetNewTabBackgroundCSS(const ui::ThemeProvider * theme_provider,bool bar_attached)115 std::string GetNewTabBackgroundCSS(const ui::ThemeProvider* theme_provider,
116 bool bar_attached) {
117 // TODO(glen): This is a quick workaround to hide the notused.png image when
118 // no image is provided - we don't have time right now to figure out why
119 // this is painting as white.
120 // http://crbug.com/17593
121 if (!theme_provider->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
122 return "-64px";
123 }
124
125 int alignment = theme_provider->GetDisplayProperty(
126 ThemeProperties::NTP_BACKGROUND_ALIGNMENT);
127
128 if (bar_attached)
129 return ThemeProperties::AlignmentToString(alignment);
130
131 if (alignment & ThemeProperties::ALIGN_TOP) {
132 // The bar is detached, so we must offset the background by the bar size
133 // if it's a top-aligned bar.
134 int offset = chrome::kNTPBookmarkBarHeight;
135
136 if (alignment & ThemeProperties::ALIGN_LEFT)
137 return "left " + base::IntToString(-offset) + "px";
138 else if (alignment & ThemeProperties::ALIGN_RIGHT)
139 return "right " + base::IntToString(-offset) + "px";
140 return "center " + base::IntToString(-offset) + "px";
141 }
142
143 return ThemeProperties::AlignmentToString(alignment);
144 }
145
146 // How the background image on the new tab page should be tiled (see tiling
147 // masks in theme_service.h).
GetNewTabBackgroundTilingCSS(const ui::ThemeProvider * theme_provider)148 std::string GetNewTabBackgroundTilingCSS(
149 const ui::ThemeProvider* theme_provider) {
150 int repeat_mode = theme_provider->GetDisplayProperty(
151 ThemeProperties::NTP_BACKGROUND_TILING);
152 return ThemeProperties::TilingToString(repeat_mode);
153 }
154
155 } // namespace
156
NTPResourceCache(Profile * profile)157 NTPResourceCache::NTPResourceCache(Profile* profile)
158 : profile_(profile), is_swipe_tracking_from_scroll_events_enabled_(false),
159 should_show_apps_page_(NewTabUI::ShouldShowApps()),
160 should_show_most_visited_page_(true),
161 should_show_other_devices_menu_(true),
162 should_show_recently_closed_menu_(true) {
163 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
164 content::Source<ThemeService>(
165 ThemeServiceFactory::GetForProfile(profile)));
166 registrar_.Add(this, chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED,
167 content::NotificationService::AllSources());
168
169 base::Closure callback = base::Bind(&NTPResourceCache::OnPreferenceChanged,
170 base::Unretained(this));
171
172 // Watch for pref changes that cause us to need to invalidate the HTML cache.
173 profile_pref_change_registrar_.Init(profile_->GetPrefs());
174 profile_pref_change_registrar_.Add(prefs::kShowBookmarkBar, callback);
175 profile_pref_change_registrar_.Add(prefs::kNtpShownPage, callback);
176 profile_pref_change_registrar_.Add(prefs::kSignInPromoShowNTPBubble,
177 callback);
178 profile_pref_change_registrar_.Add(prefs::kHideWebStoreIcon, callback);
179
180 // Some tests don't have a local state.
181 #if defined(ENABLE_APP_LIST)
182 if (g_browser_process->local_state()) {
183 local_state_pref_change_registrar_.Init(g_browser_process->local_state());
184 local_state_pref_change_registrar_.Add(prefs::kShowAppLauncherPromo,
185 callback);
186 local_state_pref_change_registrar_.Add(
187 prefs::kAppLauncherHasBeenEnabled, callback);
188 }
189 #endif
190 }
191
~NTPResourceCache()192 NTPResourceCache::~NTPResourceCache() {}
193
NewTabCacheNeedsRefresh()194 bool NTPResourceCache::NewTabCacheNeedsRefresh() {
195 #if defined(OS_MACOSX)
196 // Invalidate if the current value is different from the cached value.
197 bool is_enabled = platform_util::IsSwipeTrackingFromScrollEventsEnabled();
198 if (is_enabled != is_swipe_tracking_from_scroll_events_enabled_) {
199 is_swipe_tracking_from_scroll_events_enabled_ = is_enabled;
200 return true;
201 }
202 #endif
203 bool should_show_apps_page = NewTabUI::ShouldShowApps();
204 if (should_show_apps_page != should_show_apps_page_) {
205 should_show_apps_page_ = should_show_apps_page;
206 return true;
207 }
208 return false;
209 }
210
GetWindowType(Profile * profile,content::RenderProcessHost * render_host)211 NTPResourceCache::WindowType NTPResourceCache::GetWindowType(
212 Profile* profile, content::RenderProcessHost* render_host) {
213 if (profile->IsGuestSession()) {
214 return NTPResourceCache::GUEST;
215 } else if (render_host) {
216 // Sometimes the |profile| is the parent (non-incognito) version of the user
217 // so we check the |render_host| if it is provided.
218 if (render_host->GetBrowserContext()->IsOffTheRecord())
219 return NTPResourceCache::INCOGNITO;
220 } else if (profile->IsOffTheRecord()) {
221 return NTPResourceCache::INCOGNITO;
222 }
223 return NTPResourceCache::NORMAL;
224 }
225
GetNewTabHTML(WindowType win_type)226 base::RefCountedMemory* NTPResourceCache::GetNewTabHTML(WindowType win_type) {
227 DCHECK_CURRENTLY_ON(BrowserThread::UI);
228 if (win_type == GUEST) {
229 if (!new_tab_guest_html_.get())
230 CreateNewTabGuestHTML();
231 return new_tab_guest_html_.get();
232 } else if (win_type == INCOGNITO) {
233 if (!new_tab_incognito_html_.get())
234 CreateNewTabIncognitoHTML();
235 return new_tab_incognito_html_.get();
236 } else {
237 // Refresh the cached HTML if necessary.
238 // NOTE: NewTabCacheNeedsRefresh() must be called every time the new tab
239 // HTML is fetched, because it needs to initialize cached values.
240 if (NewTabCacheNeedsRefresh() || !new_tab_html_.get())
241 CreateNewTabHTML();
242 return new_tab_html_.get();
243 }
244 }
245
GetNewTabCSS(WindowType win_type)246 base::RefCountedMemory* NTPResourceCache::GetNewTabCSS(WindowType win_type) {
247 DCHECK_CURRENTLY_ON(BrowserThread::UI);
248 if (win_type == GUEST) {
249 if (!new_tab_guest_css_.get())
250 CreateNewTabGuestCSS();
251 return new_tab_guest_css_.get();
252 } else if (win_type == INCOGNITO) {
253 if (!new_tab_incognito_css_.get())
254 CreateNewTabIncognitoCSS();
255 return new_tab_incognito_css_.get();
256 } else {
257 if (!new_tab_css_.get())
258 CreateNewTabCSS();
259 return new_tab_css_.get();
260 }
261 }
262
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)263 void NTPResourceCache::Observe(int type,
264 const content::NotificationSource& source,
265 const content::NotificationDetails& details) {
266 // Invalidate the cache.
267 if (chrome::NOTIFICATION_BROWSER_THEME_CHANGED == type ||
268 chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED == type) {
269 new_tab_incognito_html_ = NULL;
270 new_tab_html_ = NULL;
271 new_tab_incognito_css_ = NULL;
272 new_tab_css_ = NULL;
273 } else {
274 NOTREACHED();
275 }
276 }
277
OnPreferenceChanged()278 void NTPResourceCache::OnPreferenceChanged() {
279 // A change occurred to one of the preferences we care about, so flush the
280 // cache.
281 new_tab_incognito_html_ = NULL;
282 new_tab_html_ = NULL;
283 new_tab_css_ = NULL;
284 }
285
CreateNewTabIncognitoHTML()286 void NTPResourceCache::CreateNewTabIncognitoHTML() {
287 base::DictionaryValue localized_strings;
288 localized_strings.SetString("title",
289 l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
290 int new_tab_description_ids = IDS_NEW_TAB_OTR_DESCRIPTION;
291 int new_tab_heading_ids = IDS_NEW_TAB_OTR_HEADING;
292 int new_tab_link_ids = IDS_NEW_TAB_OTR_LEARN_MORE_LINK;
293 int new_tab_warning_ids = IDS_NEW_TAB_OTR_MESSAGE_WARNING;
294 int new_tab_html_idr = IDR_INCOGNITO_TAB_HTML;
295 const char* new_tab_link = kLearnMoreIncognitoUrl;
296
297 if (profile_->IsGuestSession()) {
298 localized_strings.SetString("guestTabDescription",
299 l10n_util::GetStringUTF16(new_tab_description_ids));
300 localized_strings.SetString("guestTabHeading",
301 l10n_util::GetStringUTF16(new_tab_heading_ids));
302 } else {
303 localized_strings.SetString("incognitoTabDescription",
304 l10n_util::GetStringUTF16(new_tab_description_ids));
305 localized_strings.SetString("incognitoTabHeading",
306 l10n_util::GetStringUTF16(new_tab_heading_ids));
307 localized_strings.SetString("incognitoTabWarning",
308 l10n_util::GetStringUTF16(new_tab_warning_ids));
309 }
310
311 localized_strings.SetString("learnMore",
312 l10n_util::GetStringUTF16(new_tab_link_ids));
313 localized_strings.SetString("learnMoreLink", new_tab_link);
314
315 bool bookmark_bar_attached = profile_->GetPrefs()->GetBoolean(
316 prefs::kShowBookmarkBar);
317 localized_strings.SetBoolean("bookmarkbarattached", bookmark_bar_attached);
318
319 webui::SetFontAndTextDirection(&localized_strings);
320
321 static const base::StringPiece incognito_tab_html(
322 ResourceBundle::GetSharedInstance().GetRawDataResource(
323 new_tab_html_idr));
324
325 std::string full_html = webui::GetI18nTemplateHtml(
326 incognito_tab_html, &localized_strings);
327
328 new_tab_incognito_html_ = base::RefCountedString::TakeString(&full_html);
329 }
330
CreateNewTabGuestHTML()331 void NTPResourceCache::CreateNewTabGuestHTML() {
332 base::DictionaryValue localized_strings;
333 localized_strings.SetString("title",
334 l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
335 const char* guest_tab_link = kLearnMoreGuestSessionUrl;
336 int guest_tab_ids = IDR_GUEST_TAB_HTML;
337 int guest_tab_description_ids = IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION;
338 int guest_tab_heading_ids = IDS_NEW_TAB_GUEST_SESSION_HEADING;
339 int guest_tab_link_ids = IDS_NEW_TAB_GUEST_SESSION_LEARN_MORE_LINK;
340
341 #if defined(OS_CHROMEOS)
342 guest_tab_ids = IDR_GUEST_SESSION_TAB_HTML;
343 guest_tab_link = kLearnMoreGuestSessionUrl;
344
345 policy::BrowserPolicyConnectorChromeOS* connector =
346 g_browser_process->platform_part()->browser_policy_connector_chromeos();
347 std::string enterprise_domain = connector->GetEnterpriseDomain();
348
349 if (!enterprise_domain.empty()) {
350 // Device is enterprise enrolled.
351 localized_strings.SetString("enterpriseInfoVisible", "true");
352 base::string16 enterprise_info = l10n_util::GetStringFUTF16(
353 IDS_DEVICE_OWNED_BY_NOTICE,
354 base::UTF8ToUTF16(enterprise_domain));
355 localized_strings.SetString("enterpriseInfoMessage", enterprise_info);
356 localized_strings.SetString("enterpriseLearnMore",
357 l10n_util::GetStringUTF16(IDS_LEARN_MORE));
358 localized_strings.SetString("enterpriseInfoHintLink",
359 chrome::kLearnMoreEnterpriseURL);
360 } else {
361 localized_strings.SetString("enterpriseInfoVisible", "false");
362 }
363 #endif
364
365 localized_strings.SetString("guestTabDescription",
366 l10n_util::GetStringUTF16(guest_tab_description_ids));
367 localized_strings.SetString("guestTabHeading",
368 l10n_util::GetStringUTF16(guest_tab_heading_ids));
369 localized_strings.SetString("learnMore",
370 l10n_util::GetStringUTF16(guest_tab_link_ids));
371 localized_strings.SetString("learnMoreLink", guest_tab_link);
372
373 webui::SetFontAndTextDirection(&localized_strings);
374
375 static const base::StringPiece guest_tab_html(
376 ResourceBundle::GetSharedInstance().GetRawDataResource(guest_tab_ids));
377
378 std::string full_html = webui::GetI18nTemplateHtml(
379 guest_tab_html, &localized_strings);
380
381 new_tab_guest_html_ = base::RefCountedString::TakeString(&full_html);
382 }
383
CreateNewTabHTML()384 void NTPResourceCache::CreateNewTabHTML() {
385 // TODO(estade): these strings should be defined in their relevant handlers
386 // (in GetLocalizedValues) and should have more legible names.
387 // Show the profile name in the title and most visited labels if the current
388 // profile is not the default.
389 PrefService* prefs = profile_->GetPrefs();
390 base::DictionaryValue load_time_data;
391 load_time_data.SetBoolean("bookmarkbarattached",
392 prefs->GetBoolean(prefs::kShowBookmarkBar));
393 load_time_data.SetBoolean("hasattribution",
394 ThemeServiceFactory::GetForProfile(profile_)->HasCustomImage(
395 IDR_THEME_NTP_ATTRIBUTION));
396 load_time_data.SetBoolean("showMostvisited", should_show_most_visited_page_);
397 load_time_data.SetBoolean("showAppLauncherPromo",
398 ShouldShowAppLauncherPromo());
399 load_time_data.SetBoolean("showRecentlyClosed",
400 should_show_recently_closed_menu_);
401 load_time_data.SetString("title",
402 l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
403 load_time_data.SetString("mostvisited",
404 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED));
405 load_time_data.SetString("suggestions",
406 l10n_util::GetStringUTF16(IDS_NEW_TAB_SUGGESTIONS));
407 load_time_data.SetString("restoreThumbnailsShort",
408 l10n_util::GetStringUTF16(IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK));
409 load_time_data.SetString("recentlyclosed",
410 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED));
411 load_time_data.SetString("webStoreTitle",
412 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
413 load_time_data.SetString("webStoreTitleShort",
414 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE_SHORT));
415 load_time_data.SetString("closedwindowsingle",
416 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE));
417 load_time_data.SetString("closedwindowmultiple",
418 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE));
419 load_time_data.SetString("attributionintro",
420 l10n_util::GetStringUTF16(IDS_NEW_TAB_ATTRIBUTION_INTRO));
421 load_time_data.SetString("thumbnailremovednotification",
422 l10n_util::GetStringUTF16(IDS_NEW_TAB_THUMBNAIL_REMOVED_NOTIFICATION));
423 load_time_data.SetString("undothumbnailremove",
424 l10n_util::GetStringUTF16(IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE));
425 load_time_data.SetString("removethumbnailtooltip",
426 l10n_util::GetStringUTF16(IDS_NEW_TAB_REMOVE_THUMBNAIL_TOOLTIP));
427 load_time_data.SetString("appuninstall",
428 l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL));
429 load_time_data.SetString("appoptions",
430 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_OPTIONS));
431 load_time_data.SetString("appdetails",
432 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_DETAILS));
433 load_time_data.SetString("appcreateshortcut",
434 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_CREATE_SHORTCUT));
435 load_time_data.SetString("appDefaultPageName",
436 l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME));
437 load_time_data.SetString("applaunchtypepinned",
438 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
439 load_time_data.SetString("applaunchtyperegular",
440 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
441 load_time_data.SetString("applaunchtypewindow",
442 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
443 load_time_data.SetString("applaunchtypefullscreen",
444 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
445 load_time_data.SetString("syncpromotext",
446 l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL));
447 load_time_data.SetString("syncLinkText",
448 l10n_util::GetStringUTF16(IDS_SYNC_ADVANCED_OPTIONS));
449 load_time_data.SetBoolean("shouldShowSyncLogin",
450 NTPLoginHandler::ShouldShow(profile_));
451 load_time_data.SetString("otherSessions",
452 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_LABEL));
453 load_time_data.SetString("otherSessionsEmpty",
454 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_EMPTY));
455 load_time_data.SetString("otherSessionsLearnMoreUrl",
456 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_LEARN_MORE_URL));
457 load_time_data.SetString("learnMore",
458 l10n_util::GetStringUTF16(IDS_LEARN_MORE));
459 load_time_data.SetString("webStoreLink",
460 google_util::AppendGoogleLocaleParam(
461 GURL(extension_urls::GetWebstoreLaunchURL()),
462 g_browser_process->GetApplicationLocale()).spec());
463 load_time_data.SetString("appInstallHintText",
464 l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_INSTALL_HINT_LABEL));
465 load_time_data.SetBoolean("isDiscoveryInNTPEnabled",
466 NewTabUI::IsDiscoveryInNTPEnabled());
467 load_time_data.SetString("collapseSessionMenuItemText",
468 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_COLLAPSE_SESSION));
469 load_time_data.SetString("expandSessionMenuItemText",
470 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_EXPAND_SESSION));
471 load_time_data.SetString("restoreSessionMenuItemText",
472 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_OPEN_ALL));
473 load_time_data.SetString("learn_more",
474 l10n_util::GetStringUTF16(IDS_LEARN_MORE));
475 load_time_data.SetString("tile_grid_screenreader_accessible_description",
476 l10n_util::GetStringUTF16(IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION));
477 load_time_data.SetString("page_switcher_change_title",
478 l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE));
479 load_time_data.SetString("page_switcher_same_title",
480 l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE));
481 load_time_data.SetString("appsPromoTitle",
482 l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_APPS_PROMO_TITLE));
483 // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or
484 // forward gesture. Pass through a flag that indicates whether or not that
485 // feature is enabled.
486 load_time_data.SetBoolean("isSwipeTrackingFromScrollEventsEnabled",
487 is_swipe_tracking_from_scroll_events_enabled_);
488 // Supervised users can not have apps installed currently so there's no need
489 // to show the app cards.
490 if (profile_->IsSupervised())
491 should_show_apps_page_ = false;
492
493 load_time_data.SetBoolean("showApps", should_show_apps_page_);
494 load_time_data.SetBoolean("showWebStoreIcon",
495 !prefs->GetBoolean(prefs::kHideWebStoreIcon));
496
497 bool streamlined_hosted_apps = CommandLine::ForCurrentProcess()->HasSwitch(
498 switches::kEnableStreamlinedHostedApps);
499 load_time_data.SetBoolean("enableStreamlinedHostedApps",
500 streamlined_hosted_apps);
501 // Use a different string for launching as a regular tab for streamlined
502 // hosted apps.
503 if (streamlined_hosted_apps) {
504 load_time_data.SetString("applaunchtypetab",
505 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB));
506 }
507
508 #if defined(OS_CHROMEOS)
509 load_time_data.SetString("expandMenu",
510 l10n_util::GetStringUTF16(IDS_NEW_TAB_CLOSE_MENU_EXPAND));
511 #endif
512
513 NewTabPageHandler::GetLocalizedValues(profile_, &load_time_data);
514 NTPLoginHandler::GetLocalizedValues(profile_, &load_time_data);
515
516 webui::SetFontAndTextDirection(&load_time_data);
517
518 // Control fade and resize animations.
519 load_time_data.SetBoolean("anim",
520 gfx::Animation::ShouldRenderRichAnimation());
521
522 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
523 int alignment = tp->GetDisplayProperty(
524 ThemeProperties::NTP_BACKGROUND_ALIGNMENT);
525 load_time_data.SetString("themegravity",
526 (alignment & ThemeProperties::ALIGN_RIGHT) ? "right" : "");
527
528 // Disable the promo if this is the first run, otherwise set the promo string
529 // for display if there is a valid outstanding promo.
530 if (first_run::IsChromeFirstRun()) {
531 NotificationPromo::HandleClosed(NotificationPromo::NTP_NOTIFICATION_PROMO);
532 } else {
533 NotificationPromo notification_promo;
534 notification_promo.InitFromPrefs(NotificationPromo::NTP_NOTIFICATION_PROMO);
535 if (notification_promo.CanShow()) {
536 load_time_data.SetString("notificationPromoText",
537 notification_promo.promo_text());
538 DVLOG(1) << "Notification promo:" << notification_promo.promo_text();
539 }
540
541 NotificationPromo bubble_promo;
542 bubble_promo.InitFromPrefs(NotificationPromo::NTP_BUBBLE_PROMO);
543 if (bubble_promo.CanShow()) {
544 load_time_data.SetString("bubblePromoText",
545 bubble_promo.promo_text());
546 DVLOG(1) << "Bubble promo:" << bubble_promo.promo_text();
547 }
548 }
549
550 // Determine whether to show the menu for accessing tabs on other devices.
551 bool show_other_sessions_menu = should_show_other_devices_menu_ &&
552 !CommandLine::ForCurrentProcess()->HasSwitch(
553 switches::kDisableNTPOtherSessionsMenu);
554 load_time_data.SetBoolean("showOtherSessionsMenu", show_other_sessions_menu);
555 load_time_data.SetBoolean("isUserSignedIn",
556 !prefs->GetString(prefs::kGoogleServicesUsername).empty());
557
558 // Load the new tab page appropriate for this build.
559 base::StringPiece new_tab_html(ResourceBundle::GetSharedInstance().
560 GetRawDataResource(IDR_NEW_TAB_4_HTML));
561 webui::UseVersion2 version2;
562 std::string full_html =
563 webui::GetI18nTemplateHtml(new_tab_html, &load_time_data);
564 new_tab_html_ = base::RefCountedString::TakeString(&full_html);
565 }
566
CreateNewTabIncognitoCSS()567 void NTPResourceCache::CreateNewTabIncognitoCSS() {
568 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
569 DCHECK(tp);
570
571 // Get our theme colors
572 SkColor color_background =
573 GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
574
575 // Generate the replacements.
576 std::vector<std::string> subst;
577
578 // Cache-buster for background.
579 subst.push_back(
580 profile_->GetPrefs()->GetString(prefs::kCurrentThemeID)); // $1
581
582 // Colors.
583 subst.push_back(SkColorToRGBAString(color_background)); // $2
584 subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
585 subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
586 subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
587
588 // Get our template.
589 static const base::StringPiece new_tab_theme_css(
590 ResourceBundle::GetSharedInstance().GetRawDataResource(
591 IDR_NEW_INCOGNITO_TAB_THEME_CSS));
592
593 // Create the string from our template and the replacements.
594 std::string full_css = ReplaceStringPlaceholders(
595 new_tab_theme_css, subst, NULL);
596
597 new_tab_incognito_css_ = base::RefCountedString::TakeString(&full_css);
598 }
599
CreateNewTabGuestCSS()600 void NTPResourceCache::CreateNewTabGuestCSS() {
601 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
602 DCHECK(tp);
603
604 // Get our theme colors
605 SkColor color_background =
606 GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
607
608 // Generate the replacements.
609 std::vector<std::string> subst;
610
611 // Cache-buster for background.
612 subst.push_back(
613 profile_->GetPrefs()->GetString(prefs::kCurrentThemeID)); // $1
614
615 // Colors.
616 subst.push_back(SkColorToRGBAString(color_background)); // $2
617 subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
618 subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
619 subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
620
621 // Get our template.
622 static const base::StringPiece new_tab_theme_css(
623 ResourceBundle::GetSharedInstance().GetRawDataResource(
624 IDR_NEW_GUEST_TAB_THEME_CSS));
625
626 // Create the string from our template and the replacements.
627 std::string full_css = ReplaceStringPlaceholders(
628 new_tab_theme_css, subst, NULL);
629
630 new_tab_guest_css_ = base::RefCountedString::TakeString(&full_css);
631 }
632
CreateNewTabCSS()633 void NTPResourceCache::CreateNewTabCSS() {
634 ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
635 DCHECK(tp);
636
637 // Get our theme colors
638 SkColor color_background =
639 GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
640 SkColor color_text = GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT);
641 SkColor color_link = GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK);
642 SkColor color_link_underline =
643 GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK_UNDERLINE);
644
645 SkColor color_section =
646 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION);
647 SkColor color_section_text =
648 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_TEXT);
649 SkColor color_section_link =
650 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_LINK);
651 SkColor color_section_link_underline =
652 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE);
653 SkColor color_section_header_text =
654 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT);
655 SkColor color_section_header_text_hover =
656 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER);
657 SkColor color_section_header_rule =
658 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE);
659 SkColor color_section_header_rule_light =
660 GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT);
661 SkColor color_text_light =
662 GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT_LIGHT);
663
664 SkColor color_header =
665 GetThemeColor(tp, ThemeProperties::COLOR_NTP_HEADER);
666 // Generate a lighter color for the header gradients.
667 color_utils::HSL header_lighter;
668 color_utils::SkColorToHSL(color_header, &header_lighter);
669 header_lighter.l += (1 - header_lighter.l) * 0.33;
670 SkColor color_header_gradient_light =
671 color_utils::HSLToSkColor(header_lighter, SkColorGetA(color_header));
672
673 // Generate section border color from the header color. See
674 // BookmarkBarView::Paint for how we do this for the bookmark bar
675 // borders.
676 SkColor color_section_border =
677 SkColorSetARGB(80,
678 SkColorGetR(color_header),
679 SkColorGetG(color_header),
680 SkColorGetB(color_header));
681
682 // Generate the replacements.
683 std::vector<std::string> subst;
684
685 // Cache-buster for background.
686 subst.push_back(
687 profile_->GetPrefs()->GetString(prefs::kCurrentThemeID)); // $1
688
689 // Colors.
690 subst.push_back(SkColorToRGBAString(color_background)); // $2
691 subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
692 subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
693 subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
694 subst.push_back(SkColorToRGBAString(color_header)); // $6
695 subst.push_back(SkColorToRGBAString(color_header_gradient_light)); // $7
696 subst.push_back(SkColorToRGBAString(color_text)); // $8
697 subst.push_back(SkColorToRGBAString(color_link)); // $9
698 subst.push_back(SkColorToRGBAString(color_section)); // $10
699 subst.push_back(SkColorToRGBAString(color_section_border)); // $11
700 subst.push_back(SkColorToRGBAString(color_section_text)); // $12
701 subst.push_back(SkColorToRGBAString(color_section_link)); // $13
702 subst.push_back(SkColorToRGBAString(color_link_underline)); // $14
703 subst.push_back(SkColorToRGBAString(color_section_link_underline)); // $15
704 subst.push_back(SkColorToRGBAString(color_section_header_text)); // $16
705 subst.push_back(SkColorToRGBAString(
706 color_section_header_text_hover)); // $17
707 subst.push_back(SkColorToRGBAString(color_section_header_rule)); // $18
708 subst.push_back(SkColorToRGBAString(
709 color_section_header_rule_light)); // $19
710 subst.push_back(SkColorToRGBAString(
711 SkColorSetA(color_section_header_rule, 0))); // $20
712 subst.push_back(SkColorToRGBAString(color_text_light)); // $21
713 subst.push_back(SkColorToRGBComponents(color_section_border)); // $22
714 subst.push_back(SkColorToRGBComponents(color_text)); // $23
715
716 // Get our template.
717 static const base::StringPiece new_tab_theme_css(
718 ResourceBundle::GetSharedInstance().GetRawDataResource(
719 IDR_NEW_TAB_4_THEME_CSS));
720
721 // Create the string from our template and the replacements.
722 std::string css_string;
723 css_string = ReplaceStringPlaceholders(new_tab_theme_css, subst, NULL);
724 new_tab_css_ = base::RefCountedString::TakeString(&css_string);
725 }
726