| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/no_destructor.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/browser_process_platform_part.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/policy/profile_policy_connector.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/signin/identity_manager_factory.h" |
| #include "chrome/browser/signin/signin_util.h" |
| #include "chrome/browser/themes/theme_properties.h" |
| #include "chrome/browser/themes/theme_service.h" |
| #include "chrome/browser/themes/theme_service_factory.h" |
| #include "chrome/browser/ui/apps/app_info_dialog.h" |
| #include "chrome/browser/ui/cookie_controls/cookie_controls_service.h" |
| #include "chrome/browser/ui/cookie_controls/cookie_controls_service_factory.h" |
| #include "chrome/browser/ui/layout_constants.h" |
| #include "chrome/browser/ui/webui/app_launcher_login_handler.h" |
| #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
| #include "chrome/browser/ui/webui/ntp/cookie_controls_handler.h" |
| #include "chrome/common/buildflags.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/grit/browser_resources.h" |
| #include "chrome/grit/chromium_strings.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/grit/theme_resources.h" |
| #include "components/bookmarks/common/bookmark_pref_names.h" |
| #include "components/content_settings/core/common/cookie_controls_enforcement.h" |
| #include "components/content_settings/core/common/pref_names.h" |
| #include "components/google/core/common/google_util.h" |
| #include "components/policy/core/common/policy_service.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "extensions/common/extension_urls.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/template_expressions.h" |
| #include "ui/base/theme_provider.h" |
| #include "ui/base/webui/jstemplate_builder.h" |
| #include "ui/base/webui/web_ui_util.h" |
| #include "ui/chromeos/devicetype_utils.h" |
| #include "ui/gfx/animation/animation.h" |
| #include "ui/gfx/color_utils.h" |
| #include "ui/native_theme/native_theme.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| #include "chromeos/strings/grit/chromeos_strings.h" |
| #endif |
| |
| #if defined(OS_MAC) |
| #include "chrome/browser/platform_util.h" |
| #endif |
| |
| using content::BrowserThread; |
| |
| namespace { |
| |
| // The URL for the the Learn More page shown on incognito new tab. |
| const char kLearnMoreIncognitoUrl[] = |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| "https://support.google.com/chromebook/?p=incognito"; |
| #else |
| "https://support.google.com/chrome/?p=incognito"; |
| #endif |
| |
| // The URL for the Learn More page shown on guest session new tab. |
| const char kLearnMoreGuestSessionUrl[] = |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| "https://support.google.com/chromebook/?p=chromebook_guest"; |
| #else |
| "https://support.google.com/chrome/?p=ui_guest"; |
| #endif |
| |
| // The URL for the Learn More page shown on ephermal guest session new tab. |
| const char kLearnMoreEphemeralGuestSessionUrl[] = |
| "https://support.google.com/chrome/?p=ui_guest"; |
| |
| SkColor GetThemeColor(const ui::ThemeProvider& tp, int id) { |
| SkColor color = tp.GetColor(id); |
| // If web contents are being inverted because the system is in high-contrast |
| // mode, any system theme colors we use must be inverted too to cancel out. |
| return ui::NativeTheme::GetInstanceForNativeUi() |
| ->GetPlatformHighContrastColorScheme() == |
| ui::NativeTheme::PlatformHighContrastColorScheme::kDark |
| ? color_utils::InvertColor(color) |
| : color; |
| } |
| |
| // Get the CSS string for the background position on the new tab page for the |
| // states when the bar is attached or detached. |
| std::string GetNewTabBackgroundCSS(const ui::ThemeProvider& theme_provider, |
| bool bar_attached) { |
| // TODO(glen): This is a quick workaround to hide the notused.png image when |
| // no image is provided - we don't have time right now to figure out why |
| // this is painting as white. |
| // http://crbug.com/17593 |
| if (!theme_provider.HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { |
| return "-64px"; |
| } |
| |
| int alignment = theme_provider.GetDisplayProperty( |
| ThemeProperties::NTP_BACKGROUND_ALIGNMENT); |
| |
| if (bar_attached) |
| return ThemeProperties::AlignmentToString(alignment); |
| |
| if (alignment & ThemeProperties::ALIGN_TOP) { |
| // The bar is detached, so we must offset the background by the bar size |
| // if it's a top-aligned bar. |
| int offset = GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT); |
| |
| if (alignment & ThemeProperties::ALIGN_LEFT) |
| return "left " + base::NumberToString(-offset) + "px"; |
| else if (alignment & ThemeProperties::ALIGN_RIGHT) |
| return "right " + base::NumberToString(-offset) + "px"; |
| return "center " + base::NumberToString(-offset) + "px"; |
| } |
| |
| return ThemeProperties::AlignmentToString(alignment); |
| } |
| |
| // How the background image on the new tab page should be tiled (see tiling |
| // masks in theme_service.h). |
| std::string GetNewTabBackgroundTilingCSS( |
| const ui::ThemeProvider& theme_provider) { |
| int repeat_mode = |
| theme_provider.GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_TILING); |
| return ThemeProperties::TilingToString(repeat_mode); |
| } |
| |
| std::string ReplaceTemplateExpressions( |
| const scoped_refptr<base::RefCountedMemory>& bytes, |
| const ui::TemplateReplacements& replacements) { |
| return ui::ReplaceTemplateExpressions( |
| base::StringPiece(reinterpret_cast<const char*>(bytes->front()), |
| bytes->size()), |
| replacements); |
| } |
| |
| } // namespace |
| |
| NTPResourceCache::NTPResourceCache(Profile* profile) |
| : profile_(profile), is_swipe_tracking_from_scroll_events_enabled_(false) { |
| registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
| content::Source<ThemeService>( |
| ThemeServiceFactory::GetForProfile(profile))); |
| |
| base::Closure callback = base::Bind(&NTPResourceCache::OnPreferenceChanged, |
| base::Unretained(this)); |
| |
| // Watch for pref changes that cause us to need to invalidate the HTML cache. |
| profile_pref_change_registrar_.Init(profile_->GetPrefs()); |
| profile_pref_change_registrar_.Add(bookmarks::prefs::kShowBookmarkBar, |
| callback); |
| profile_pref_change_registrar_.Add(prefs::kNtpShownPage, callback); |
| profile_pref_change_registrar_.Add(prefs::kHideWebStoreIcon, callback); |
| profile_pref_change_registrar_.Add(prefs::kCookieControlsMode, callback); |
| |
| theme_observer_.Add(ui::NativeTheme::GetInstanceForNativeUi()); |
| |
| policy_change_registrar_ = std::make_unique<policy::PolicyChangeRegistrar>( |
| profile->GetProfilePolicyConnector()->policy_service(), |
| policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())); |
| policy_change_registrar_->Observe( |
| policy::key::kBlockThirdPartyCookies, |
| base::BindRepeating(&NTPResourceCache::OnPolicyChanged, |
| base::Unretained(this))); |
| } |
| |
| NTPResourceCache::~NTPResourceCache() = default; |
| |
| bool NTPResourceCache::NewTabHTMLNeedsRefresh() { |
| #if defined(OS_MAC) |
| // Invalidate if the current value is different from the cached value. |
| bool is_enabled = platform_util::IsSwipeTrackingFromScrollEventsEnabled(); |
| if (is_enabled != is_swipe_tracking_from_scroll_events_enabled_) { |
| is_swipe_tracking_from_scroll_events_enabled_ = is_enabled; |
| return true; |
| } |
| #endif |
| return false; |
| } |
| |
| NTPResourceCache::WindowType NTPResourceCache::GetWindowType( |
| Profile* profile, content::RenderProcessHost* render_host) { |
| if (profile->IsGuestSession() || profile->IsEphemeralGuestProfile()) { |
| return GUEST; |
| } else if (render_host) { |
| // Sometimes the |profile| is the parent (non-incognito) version of the user |
| // so we check the |render_host| if it is provided. |
| if (render_host->GetBrowserContext()->IsOffTheRecord()) |
| return INCOGNITO; |
| } else if (profile->IsOffTheRecord()) { |
| return INCOGNITO; |
| } |
| return NORMAL; |
| } |
| |
| base::RefCountedMemory* NTPResourceCache::GetNewTabGuestHTML() { |
| // TODO(crbug.com/1134111): For full launch of ephemeral Guest profiles, |
| // instead of the below code block, use IdentityManager for ephemeral Guest |
| // profiles to check sign in status and return either |
| // |CreateNewTabEphemeralGuestSignedInHTML()| or |
| // |CreateNewTabEphemeralGuestSignedOutHTML()|. |
| if (!new_tab_guest_html_) { |
| GuestNTPInfo guest_ntp_info{kLearnMoreGuestSessionUrl, IDR_GUEST_TAB_HTML, |
| IDS_NEW_TAB_GUEST_SESSION_HEADING, |
| IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION}; |
| new_tab_guest_html_ = CreateNewTabGuestHTML(guest_ntp_info); |
| } |
| |
| return new_tab_guest_html_.get(); |
| } |
| |
| base::RefCountedMemory* NTPResourceCache::GetNewTabHTML(WindowType win_type) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (win_type == GUEST) { |
| return GetNewTabGuestHTML(); |
| } |
| |
| if (win_type == INCOGNITO) { |
| if (!new_tab_incognito_html_) |
| CreateNewTabIncognitoHTML(); |
| return new_tab_incognito_html_.get(); |
| } |
| |
| // Refresh the cached HTML if necessary. |
| // NOTE: NewTabHTMLNeedsRefresh() must be called every time the new tab |
| // HTML is fetched, because it needs to initialize cached values. |
| if (NewTabHTMLNeedsRefresh() || !new_tab_html_) |
| CreateNewTabHTML(); |
| return new_tab_html_.get(); |
| } |
| |
| base::RefCountedMemory* NTPResourceCache::GetNewTabCSS(WindowType win_type) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| |
| // Guest mode doesn't have theme-related CSS. |
| if (win_type == GUEST) |
| return nullptr; |
| |
| if (win_type == INCOGNITO) { |
| if (!new_tab_incognito_css_) |
| CreateNewTabIncognitoCSS(); |
| return new_tab_incognito_css_.get(); |
| } |
| |
| if (!new_tab_css_) |
| CreateNewTabCSS(); |
| return new_tab_css_.get(); |
| } |
| |
| void NTPResourceCache::Observe(int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type); |
| |
| // Invalidate the cache. |
| Invalidate(); |
| } |
| |
| void NTPResourceCache::OnNativeThemeUpdated(ui::NativeTheme* updated_theme) { |
| DCHECK_EQ(updated_theme, ui::NativeTheme::GetInstanceForNativeUi()); |
| Invalidate(); |
| } |
| |
| void NTPResourceCache::OnPreferenceChanged() { |
| // A change occurred to one of the preferences we care about, so flush the |
| // cache. |
| new_tab_incognito_html_ = nullptr; |
| new_tab_html_ = nullptr; |
| new_tab_css_ = nullptr; |
| } |
| |
| // TODO(dbeam): why must Invalidate() and OnPreferenceChanged() both exist? |
| void NTPResourceCache::Invalidate() { |
| new_tab_incognito_html_ = nullptr; |
| new_tab_html_ = nullptr; |
| new_tab_incognito_css_ = nullptr; |
| new_tab_css_ = nullptr; |
| new_tab_guest_html_ = nullptr; |
| new_tab_guest_signed_in_html_ = nullptr; |
| } |
| |
| void NTPResourceCache::CreateNewTabIncognitoHTML() { |
| ui::TemplateReplacements replacements; |
| // Note: there's specific rules in CSS that look for this attribute's content |
| // being equal to "true" as a string. |
| replacements["bookmarkbarattached"] = |
| profile_->GetPrefs()->GetBoolean(bookmarks::prefs::kShowBookmarkBar) |
| ? "true" |
| : "false"; |
| |
| // Ensure passing off-the-record profile; |profile_| is not an OTR profile. |
| DCHECK(!profile_->IsOffTheRecord()); |
| DCHECK(profile_->HasAnyOffTheRecordProfile()); |
| // Cookie controls service returns the same result for all off-the-record |
| // profiles, so it doesn't matter which of them we use. |
| CookieControlsService* cookie_controls_service = |
| CookieControlsServiceFactory::GetForProfile( |
| profile_->GetAllOffTheRecordProfiles()[0]); |
| |
| replacements["incognitoTabDescription"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_SUBTITLE); |
| replacements["incognitoTabHeading"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_TITLE); |
| replacements["incognitoTabWarning"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_VISIBLE); |
| replacements["learnMore"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_LEARN_MORE_LINK); |
| replacements["incognitoTabFeatures"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_NOT_SAVED); |
| replacements["learnMoreLink"] = kLearnMoreIncognitoUrl; |
| replacements["title"] = l10n_util::GetStringUTF8(IDS_NEW_TAB_TITLE); |
| replacements["cookieControlsTitle"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE); |
| replacements["cookieControlsDescription"] = |
| l10n_util::GetStringUTF8(IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL); |
| replacements["cookieControlsToggleChecked"] = |
| cookie_controls_service->GetToggleCheckedValue() ? "checked" : ""; |
| replacements["hideTooltipIcon"] = |
| cookie_controls_service->ShouldEnforceCookieControls() ? "" : "hidden"; |
| replacements["cookieControlsToolTipIcon"] = |
| CookieControlsHandler::GetEnforcementIcon( |
| cookie_controls_service->GetCookieControlsEnforcement()); |
| replacements["cookieControlsTooltipText"] = l10n_util::GetStringUTF8( |
| IDS_NEW_TAB_OTR_COOKIE_CONTROLS_CONTROLLED_TOOLTIP_TEXT); |
| |
| const ui::ThemeProvider& tp = |
| ThemeService::GetThemeProviderForProfile(profile_); |
| replacements["hasCustomBackground"] = |
| tp.HasCustomImage(IDR_THEME_NTP_BACKGROUND) ? "true" : "false"; |
| |
| const std::string& app_locale = g_browser_process->GetApplicationLocale(); |
| webui::SetLoadTimeDataDefaults(app_locale, &replacements); |
| |
| static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> |
| incognito_tab_html( |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( |
| IDR_INCOGNITO_TAB_HTML)); |
| CHECK(*incognito_tab_html); |
| |
| std::string full_html = |
| ReplaceTemplateExpressions(*incognito_tab_html, replacements); |
| |
| new_tab_incognito_html_ = base::RefCountedString::TakeString(&full_html); |
| } |
| |
| base::RefCountedMemory* |
| NTPResourceCache::CreateNewTabEphemeralGuestSignedInHTML() { |
| if (!new_tab_guest_signed_in_html_) { |
| GuestNTPInfo guest_ntp_info{ |
| kLearnMoreEphemeralGuestSessionUrl, |
| IDR_EPHEMERAL_GUEST_TAB_HTML, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_IN, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_IN, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_IN, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED}; |
| new_tab_guest_signed_in_html_ = CreateNewTabGuestHTML(guest_ntp_info); |
| } |
| |
| return new_tab_guest_signed_in_html_.get(); |
| } |
| |
| base::RefCountedMemory* |
| NTPResourceCache::CreateNewTabEphemeralGuestSignedOutHTML() { |
| // Clear cached signed in HTML on sign out to avoid loading previously cached |
| // user name from other signed in guest sessions. |
| new_tab_guest_signed_in_html_ = nullptr; |
| |
| if (!new_tab_guest_signed_out_html_) { |
| GuestNTPInfo guest_ntp_info{ |
| kLearnMoreEphemeralGuestSessionUrl, |
| IDR_EPHEMERAL_GUEST_TAB_HTML, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_HEADING_SIGNED_OUT, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SESSION_DESCRIPTION_SIGNED_OUT, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_NOT_SAVED_SIGNED_OUT, |
| IDS_NEW_TAB_EPHEMERAL_GUEST_SAVED}; |
| new_tab_guest_signed_out_html_ = CreateNewTabGuestHTML(guest_ntp_info); |
| } |
| return new_tab_guest_signed_out_html_.get(); |
| } |
| |
| scoped_refptr<base::RefCountedString> NTPResourceCache::CreateNewTabGuestHTML( |
| const GuestNTPInfo& guest_ntp_info) { |
| base::DictionaryValue localized_strings; |
| localized_strings.SetString("title", |
| l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE)); |
| int guest_tab_idr = guest_ntp_info.html_idr; |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| guest_tab_idr = IDR_GUEST_SESSION_TAB_HTML; |
| |
| policy::BrowserPolicyConnectorChromeOS* connector = |
| g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
| |
| if (connector->IsEnterpriseManaged()) { |
| localized_strings.SetString("enterpriseInfoVisible", "true"); |
| localized_strings.SetString("enterpriseLearnMore", |
| l10n_util::GetStringUTF16(IDS_LEARN_MORE)); |
| localized_strings.SetString("enterpriseInfoHintLink", |
| chrome::kLearnMoreEnterpriseURL); |
| base::string16 enterprise_info; |
| if (connector->IsCloudManaged()) { |
| const std::string enterprise_domain_manager = |
| connector->GetEnterpriseDomainManager(); |
| enterprise_info = l10n_util::GetStringFUTF16( |
| IDS_ASH_ENTERPRISE_DEVICE_MANAGED_BY, ui::GetChromeOSDeviceName(), |
| base::UTF8ToUTF16(enterprise_domain_manager)); |
| } else if (connector->IsActiveDirectoryManaged()) { |
| enterprise_info = l10n_util::GetStringFUTF16( |
| IDS_ASH_ENTERPRISE_DEVICE_MANAGED, ui::GetChromeOSDeviceName()); |
| } else { |
| NOTREACHED() << "Unknown management type"; |
| } |
| localized_strings.SetString("enterpriseInfoMessage", enterprise_info); |
| } else { |
| localized_strings.SetString("enterpriseInfoVisible", "false"); |
| localized_strings.SetString("enterpriseInfoMessage", ""); |
| localized_strings.SetString("enterpriseLearnMore", ""); |
| localized_strings.SetString("enterpriseInfoHintLink", ""); |
| } |
| #endif |
| |
| if (guest_ntp_info.features_ids != -1) { |
| localized_strings.SetString( |
| "guestTabFeatures", |
| l10n_util::GetStringUTF16(guest_ntp_info.features_ids)); |
| } |
| |
| if (guest_ntp_info.warnings_ids != -1) { |
| localized_strings.SetString( |
| "guestTabWarning", |
| l10n_util::GetStringUTF16(guest_ntp_info.warnings_ids)); |
| } |
| |
| localized_strings.SetString( |
| "guestTabDescription", |
| l10n_util::GetStringUTF16(guest_ntp_info.description_ids)); |
| // TODO(crbug.com/1134111): Replace placeholder with user's name in the |
| // greeting message when the guest sign in functionality is implemented. |
| localized_strings.SetString( |
| "guestTabHeading", l10n_util::GetStringUTF16(guest_ntp_info.heading_ids)); |
| localized_strings.SetString("learnMore", |
| l10n_util::GetStringUTF16(IDS_LEARN_MORE)); |
| localized_strings.SetString("learnMoreLink", guest_ntp_info.learn_more_link); |
| |
| const std::string& app_locale = g_browser_process->GetApplicationLocale(); |
| webui::SetLoadTimeDataDefaults(app_locale, &localized_strings); |
| |
| static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> |
| guest_tab_html( |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( |
| guest_tab_idr)); |
| CHECK(*guest_tab_html); |
| ui::TemplateReplacements replacements; |
| ui::TemplateReplacementsFromDictionaryValue(localized_strings, &replacements); |
| std::string full_html = |
| ReplaceTemplateExpressions(*guest_tab_html, replacements); |
| |
| return base::RefCountedString::TakeString(&full_html); |
| } |
| |
| // TODO(alancutter): Consider moving this utility function up somewhere where it |
| // can be shared with bookmarks_ui.cc. |
| // Ampersands are used by menus to determine which characters to use as shortcut |
| // keys. This functionality is not implemented for NTP. |
| static base::string16 GetLocalizedString(int message_id) { |
| base::string16 result = l10n_util::GetStringUTF16(message_id); |
| base::Erase(result, '&'); |
| return result; |
| } |
| |
| void NTPResourceCache::CreateNewTabHTML() { |
| // TODO(estade): these strings should be defined in their relevant handlers |
| // (in GetLocalizedValues) and should have more legible names. |
| // Show the profile name in the title and most visited labels if the current |
| // profile is not the default. |
| PrefService* prefs = profile_->GetPrefs(); |
| base::DictionaryValue load_time_data; |
| load_time_data.SetString( |
| "bookmarkbarattached", |
| prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar) ? "true" : "false"); |
| load_time_data.SetString("title", GetLocalizedString(IDS_NEW_TAB_TITLE)); |
| load_time_data.SetString("webStoreTitle", |
| GetLocalizedString(IDS_EXTENSION_WEB_STORE_TITLE)); |
| load_time_data.SetString( |
| "webStoreTitleShort", |
| GetLocalizedString(IDS_EXTENSION_WEB_STORE_TITLE_SHORT)); |
| load_time_data.SetString("attributionintro", |
| GetLocalizedString(IDS_NEW_TAB_ATTRIBUTION_INTRO)); |
| load_time_data.SetString("appuninstall", |
| GetLocalizedString(IDS_EXTENSIONS_UNINSTALL)); |
| load_time_data.SetString("appoptions", |
| GetLocalizedString(IDS_NEW_TAB_APP_OPTIONS)); |
| load_time_data.SetString("appdetails", |
| GetLocalizedString(IDS_NEW_TAB_APP_DETAILS)); |
| load_time_data.SetString("appinfodialog", |
| GetLocalizedString(IDS_APP_CONTEXT_MENU_SHOW_INFO)); |
| load_time_data.SetString("appcreateshortcut", |
| GetLocalizedString(IDS_NEW_TAB_APP_CREATE_SHORTCUT)); |
| load_time_data.SetString("appinstalllocally", |
| GetLocalizedString(IDS_NEW_TAB_APP_INSTALL_LOCALLY)); |
| load_time_data.SetString("appDefaultPageName", |
| GetLocalizedString(IDS_APP_DEFAULT_PAGE_NAME)); |
| load_time_data.SetString( |
| "applaunchtypepinned", |
| GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_PINNED)); |
| load_time_data.SetString( |
| "applaunchtyperegular", |
| GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_REGULAR)); |
| load_time_data.SetString( |
| "applaunchtypewindow", |
| GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_WINDOW)); |
| load_time_data.SetString( |
| "applaunchtypefullscreen", |
| GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN)); |
| load_time_data.SetString( |
| "syncpromotext", GetLocalizedString(IDS_SYNC_START_SYNC_BUTTON_LABEL)); |
| load_time_data.SetString("syncLinkText", |
| GetLocalizedString(IDS_SYNC_ADVANCED_OPTIONS)); |
| load_time_data.SetBoolean("shouldShowSyncLogin", |
| AppLauncherLoginHandler::ShouldShow(profile_)); |
| load_time_data.SetString("learnMore", GetLocalizedString(IDS_LEARN_MORE)); |
| const std::string& app_locale = g_browser_process->GetApplicationLocale(); |
| load_time_data.SetString( |
| "webStoreLink", google_util::AppendGoogleLocaleParam( |
| extension_urls::GetWebstoreLaunchURL(), app_locale) |
| .spec()); |
| load_time_data.SetString( |
| "appInstallHintText", |
| GetLocalizedString(IDS_NEW_TAB_APP_INSTALL_HINT_LABEL)); |
| load_time_data.SetString("learn_more", GetLocalizedString(IDS_LEARN_MORE)); |
| load_time_data.SetString( |
| "tile_grid_screenreader_accessible_description", |
| GetLocalizedString(IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION)); |
| load_time_data.SetString( |
| "page_switcher_change_title", |
| GetLocalizedString(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE)); |
| load_time_data.SetString( |
| "page_switcher_same_title", |
| GetLocalizedString(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE)); |
| load_time_data.SetString( |
| "runonoslogin", GetLocalizedString(IDS_APP_CONTEXT_MENU_RUN_ON_OS_LOGIN)); |
| |
| // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or |
| // forward gesture. Pass through a flag that indicates whether or not that |
| // feature is enabled. |
| load_time_data.SetBoolean("isSwipeTrackingFromScrollEventsEnabled", |
| is_swipe_tracking_from_scroll_events_enabled_); |
| |
| load_time_data.SetBoolean("showWebStoreIcon", |
| !prefs->GetBoolean(prefs::kHideWebStoreIcon)); |
| |
| load_time_data.SetBoolean("canShowAppInfoDialog", |
| CanPlatformShowAppInfoDialog()); |
| |
| AppLauncherHandler::GetLocalizedValues(profile_, &load_time_data); |
| |
| webui::SetLoadTimeDataDefaults(app_locale, &load_time_data); |
| |
| // Control fade and resize animations. |
| load_time_data.SetBoolean("anim", |
| gfx::Animation::ShouldRenderRichAnimation()); |
| |
| load_time_data.SetBoolean( |
| "isUserSignedIn", |
| IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount()); |
| |
| // Load the new tab page template and localize it. |
| static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> |
| new_tab_html( |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( |
| IDR_NEW_TAB_4_HTML)); |
| CHECK(*new_tab_html); |
| std::string full_html = webui::GetI18nTemplateHtml( |
| base::StringPiece(reinterpret_cast<const char*>((*new_tab_html)->front()), |
| (*new_tab_html)->size()), |
| &load_time_data); |
| new_tab_html_ = base::RefCountedString::TakeString(&full_html); |
| } |
| |
| void NTPResourceCache::CreateNewTabIncognitoCSS() { |
| // Same theme is used by all off-the-record profiles, so just getting it from |
| // the first one. |
| const ui::ThemeProvider& tp = ThemeService::GetThemeProviderForProfile( |
| profile_->GetAllOffTheRecordProfiles()[0]); |
| |
| // Generate the replacements. |
| ui::TemplateReplacements substitutions; |
| |
| // Cache-buster for background. |
| substitutions["themeId"] = |
| profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); |
| |
| // Colors. |
| substitutions["colorBackground"] = color_utils::SkColorToRgbaString( |
| GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND)); |
| substitutions["backgroundBarDetached"] = GetNewTabBackgroundCSS(tp, false); |
| substitutions["backgroundBarAttached"] = GetNewTabBackgroundCSS(tp, true); |
| substitutions["backgroundTiling"] = GetNewTabBackgroundTilingCSS(tp); |
| |
| // Get our template. |
| static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> |
| new_tab_theme_css( |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( |
| IDR_INCOGNITO_TAB_THEME_CSS)); |
| CHECK(*new_tab_theme_css); |
| |
| // Create the string from our template and the replacements. |
| std::string full_css = |
| ReplaceTemplateExpressions(*new_tab_theme_css, substitutions); |
| |
| new_tab_incognito_css_ = base::RefCountedString::TakeString(&full_css); |
| } |
| |
| void NTPResourceCache::CreateNewTabCSS() { |
| const ui::ThemeProvider& tp = |
| ThemeService::GetThemeProviderForProfile(profile_); |
| |
| // Get our theme colors. |
| SkColor color_background = |
| GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND); |
| SkColor color_text = GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT); |
| SkColor color_text_light = |
| GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT_LIGHT); |
| |
| SkColor color_header = |
| GetThemeColor(tp, ThemeProperties::COLOR_NTP_HEADER); |
| // Generate a lighter color for the header gradients. |
| color_utils::HSL header_lighter; |
| color_utils::SkColorToHSL(color_header, &header_lighter); |
| header_lighter.l += (1 - header_lighter.l) * 0.33; |
| |
| // Generate section border color from the header color. See |
| // BookmarkBarView::Paint for how we do this for the bookmark bar |
| // borders. |
| SkColor color_section_border = |
| SkColorSetARGB(80, |
| SkColorGetR(color_header), |
| SkColorGetG(color_header), |
| SkColorGetB(color_header)); |
| |
| // Generate the replacements. |
| ui::TemplateReplacements substitutions; |
| |
| // Cache-buster for background. |
| substitutions["themeId"] = |
| profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); |
| |
| // Colors. |
| substitutions["colorBackground"] = |
| color_utils::SkColorToRgbaString(color_background); |
| substitutions["colorLink"] = color_utils::SkColorToRgbString( |
| GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK)); |
| substitutions["backgroundBarDetached"] = GetNewTabBackgroundCSS(tp, false); |
| substitutions["backgroundBarAttached"] = GetNewTabBackgroundCSS(tp, true); |
| substitutions["backgroundTiling"] = GetNewTabBackgroundTilingCSS(tp); |
| substitutions["colorTextRgba"] = color_utils::SkColorToRgbaString(color_text); |
| substitutions["colorTextLight"] = |
| color_utils::SkColorToRgbaString(color_text_light); |
| substitutions["colorSectionBorder"] = |
| color_utils::SkColorToRgbString(color_section_border); |
| substitutions["colorText"] = color_utils::SkColorToRgbString(color_text); |
| |
| // For themes that right-align the background, we flip the attribution to the |
| // left to avoid conflicts. |
| int alignment = |
| tp.GetDisplayProperty(ThemeProperties::NTP_BACKGROUND_ALIGNMENT); |
| if (alignment & ThemeProperties::ALIGN_RIGHT) { |
| substitutions["leftAlignAttribution"] = "0"; |
| substitutions["rightAlignAttribution"] = "auto"; |
| substitutions["textAlignAttribution"] = "right"; |
| } else { |
| substitutions["leftAlignAttribution"] = "auto"; |
| substitutions["rightAlignAttribution"] = "0"; |
| substitutions["textAlignAttribution"] = "left"; |
| } |
| |
| substitutions["displayAttribution"] = |
| tp.HasCustomImage(IDR_THEME_NTP_ATTRIBUTION) ? "inline" : "none"; |
| |
| // Get our template. |
| static const base::NoDestructor<scoped_refptr<base::RefCountedMemory>> |
| new_tab_theme_css( |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( |
| IDR_NEW_TAB_4_THEME_CSS)); |
| CHECK(*new_tab_theme_css); |
| |
| // Create the string from our template and the replacements. |
| std::string css_string = |
| ReplaceTemplateExpressions(*new_tab_theme_css, substitutions); |
| new_tab_css_ = base::RefCountedString::TakeString(&css_string); |
| } |
| |
| void NTPResourceCache::OnPolicyChanged(const base::Value* previous, |
| const base::Value* current) { |
| new_tab_incognito_html_ = nullptr; |
| } |