| // Copyright 2019 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/new_tab_page/new_tab_page_ui.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "chrome/browser/buildflags.h" |
| #include "chrome/browser/cart/cart_handler.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search/drive/drive_handler.h" |
| #include "chrome/browser/search/instant_service.h" |
| #include "chrome/browser/search/instant_service_factory.h" |
| #include "chrome/browser/search/task_module/task_module_handler.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/browser/ui/search/omnibox_mojo_utils.h" |
| #include "chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.h" |
| #include "chrome/browser/ui/webui/favicon_source.h" |
| #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h" |
| #include "chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h" |
| #include "chrome/browser/ui/webui/new_tab_page/untrusted_source.h" |
| #include "chrome/browser/ui/webui/sanitized_image_source.h" |
| #include "chrome/browser/ui/webui/theme_source.h" |
| #include "chrome/browser/ui/webui/webui_util.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/grit/browser_resources.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/grit/new_tab_page_resources.h" |
| #include "chrome/grit/new_tab_page_resources_map.h" |
| #include "components/favicon_base/favicon_url_parser.h" |
| #include "components/google/core/common/google_util.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/search/ntp_features.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/url_data_source.h" |
| #include "content/public/browser/web_ui_data_source.h" |
| #include "media/base/media_switches.h" |
| #include "services/network/public/mojom/content_security_policy.mojom.h" |
| #include "ui/base/accelerators/accelerator.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/webui/web_ui_util.h" |
| #include "ui/resources/grit/webui_generated_resources.h" |
| #include "url/url_util.h" |
| |
| #if !defined(OFFICIAL_BUILD) |
| #include "chrome/browser/ui/webui/new_tab_page/foo/foo_handler.h" |
| #endif |
| |
| using content::BrowserContext; |
| using content::WebContents; |
| |
| namespace { |
| |
| content::WebUIDataSource* CreateNewTabPageUiHtmlSource(Profile* profile) { |
| content::WebUIDataSource* source = |
| content::WebUIDataSource::Create(chrome::kChromeUINewTabPageHost); |
| |
| ui::Accelerator undo_accelerator(ui::VKEY_Z, ui::EF_PLATFORM_ACCELERATOR); |
| source->AddString("undoDescription", l10n_util::GetStringFUTF16( |
| IDS_UNDO_DESCRIPTION, |
| undo_accelerator.GetShortcutText())); |
| source->AddString("googleBaseUrl", |
| GURL(TemplateURLServiceFactory::GetForProfile(profile) |
| ->search_terms_data() |
| .GoogleBaseURLValue()) |
| .spec()); |
| |
| // Realbox. |
| source->AddBoolean("realboxEnabled", true); |
| source->AddBoolean( |
| "realboxMatchOmniboxTheme", |
| base::FeatureList::IsEnabled(ntp_features::kRealboxMatchOmniboxTheme)); |
| source->AddString( |
| "realboxDefaultIcon", |
| base::FeatureList::IsEnabled(ntp_features::kRealboxUseGoogleGIcon) |
| ? omnibox::kGoogleGIconResourceName |
| : omnibox::kSearchIconResourceName); |
| source->AddString("realboxHint", l10n_util::GetStringUTF8( |
| IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD)); |
| |
| source->AddBoolean( |
| "handleMostVisitedNavigationExplicitly", |
| base::FeatureList::IsEnabled( |
| ntp_features::kNtpHandleMostVisitedNavigationExplicitly)); |
| |
| source->AddBoolean( |
| "iframeOneGoogleBarEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kIframeOneGoogleBar)); |
| source->AddBoolean( |
| "oneGoogleBarModalOverlaysEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kOneGoogleBarModalOverlays)); |
| |
| source->AddBoolean( |
| "themeModeDoodlesEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kWebUIThemeModeDoodles)); |
| source->AddBoolean("modulesEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kModules)); |
| |
| static constexpr webui::LocalizedString kStrings[] = { |
| {"doneButton", IDS_DONE}, |
| {"title", IDS_NEW_TAB_TITLE}, |
| {"undo", IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE}, |
| {"controlledSettingPolicy", IDS_CONTROLLED_SETTING_POLICY}, |
| |
| // Custom Links. |
| {"addLinkTitle", IDS_NTP_CUSTOM_LINKS_ADD_SHORTCUT_TITLE}, |
| {"editLinkTitle", IDS_NTP_CUSTOM_LINKS_EDIT_SHORTCUT}, |
| {"invalidUrl", IDS_NTP_CUSTOM_LINKS_INVALID_URL}, |
| {"linkAddedMsg", IDS_NTP_CONFIRM_MSG_SHORTCUT_ADDED}, |
| {"linkCancel", IDS_NTP_CUSTOM_LINKS_CANCEL}, |
| {"linkCantCreate", IDS_NTP_CUSTOM_LINKS_CANT_CREATE}, |
| {"linkCantEdit", IDS_NTP_CUSTOM_LINKS_CANT_EDIT}, |
| {"linkDone", IDS_NTP_CUSTOM_LINKS_DONE}, |
| {"linkEditedMsg", IDS_NTP_CONFIRM_MSG_SHORTCUT_EDITED}, |
| {"linkRemove", IDS_NTP_CUSTOM_LINKS_REMOVE}, |
| {"linkRemovedMsg", IDS_NTP_CONFIRM_MSG_SHORTCUT_REMOVED}, |
| {"moreActions", IDS_SETTINGS_MORE_ACTIONS}, |
| {"nameField", IDS_NTP_CUSTOM_LINKS_NAME}, |
| {"restoreDefaultLinks", IDS_NTP_CONFIRM_MSG_RESTORE_DEFAULTS}, |
| {"restoreThumbnailsShort", IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK}, |
| {"shortcutAlreadyExists", IDS_NTP_CUSTOM_LINKS_ALREADY_EXISTS}, |
| {"urlField", IDS_NTP_CUSTOM_LINKS_URL}, |
| |
| // Customize button and dialog. |
| {"backButton", IDS_ACCNAME_BACK}, |
| {"backgroundsMenuItem", IDS_NTP_CUSTOMIZE_MENU_BACKGROUND_LABEL}, |
| {"cancelButton", IDS_CANCEL}, |
| {"colorPickerLabel", IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL}, |
| {"customBackgroundDisabled", |
| IDS_NTP_CUSTOMIZE_MENU_BACKGROUND_DISABLED_LABEL}, |
| {"customizeButton", IDS_NTP_CUSTOMIZE_BUTTON_LABEL}, |
| {"customizeThisPage", IDS_NTP_CUSTOM_BG_CUSTOMIZE_NTP_LABEL}, |
| {"defaultThemeLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL}, |
| {"hideShortcuts", IDS_NTP_CUSTOMIZE_HIDE_SHORTCUTS_LABEL}, |
| {"hideShortcutsDesc", IDS_NTP_CUSTOMIZE_HIDE_SHORTCUTS_DESC}, |
| {"showModules", IDS_NTP_CUSTOMIZE_SHOW_MODULES_LABEL}, |
| {"mostVisited", IDS_NTP_CUSTOMIZE_MOST_VISITED_LABEL}, |
| {"myShortcuts", IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_LABEL}, |
| {"noBackground", IDS_NTP_CUSTOMIZE_NO_BACKGROUND_LABEL}, |
| {"refreshDaily", IDS_NTP_CUSTOM_BG_DAILY_REFRESH}, |
| {"shortcutsCurated", IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_DESC}, |
| {"shortcutsMenuItem", IDS_NTP_CUSTOMIZE_MENU_SHORTCUTS_LABEL}, |
| {"modulesMenuItem", IDS_NTP_CUSTOMIZE_MENU_MODULES_LABEL}, |
| {"shortcutsOption", IDS_NTP_CUSTOMIZE_MENU_SHORTCUTS_LABEL}, |
| {"shortcutsSuggested", IDS_NTP_CUSTOMIZE_MOST_VISITED_DESC}, |
| {"themesMenuItem", IDS_NTP_CUSTOMIZE_MENU_COLOR_LABEL}, |
| {"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC}, |
| {"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL}, |
| {"uploadFromDevice", IDS_NTP_CUSTOMIZE_UPLOAD_FROM_DEVICE_LABEL}, |
| |
| // Voice search. |
| {"audioError", IDS_NEW_TAB_VOICE_AUDIO_ERROR}, |
| {"close", IDS_NEW_TAB_VOICE_CLOSE_TOOLTIP}, |
| {"details", IDS_NEW_TAB_VOICE_DETAILS}, |
| {"languageError", IDS_NEW_TAB_VOICE_LANGUAGE_ERROR}, |
| {"learnMore", IDS_LEARN_MORE}, |
| {"listening", IDS_NEW_TAB_VOICE_LISTENING}, |
| {"networkError", IDS_NEW_TAB_VOICE_NETWORK_ERROR}, |
| {"noTranslation", IDS_NEW_TAB_VOICE_NO_TRANSLATION}, |
| {"noVoice", IDS_NEW_TAB_VOICE_NO_VOICE}, |
| {"otherError", IDS_NEW_TAB_VOICE_OTHER_ERROR}, |
| {"permissionError", IDS_NEW_TAB_VOICE_PERMISSION_ERROR}, |
| {"speak", IDS_NEW_TAB_VOICE_READY}, |
| {"tryAgain", IDS_NEW_TAB_VOICE_TRY_AGAIN}, |
| {"voiceSearchButtonLabel", IDS_TOOLTIP_MIC_SEARCH}, |
| {"waiting", IDS_NEW_TAB_VOICE_WAITING}, |
| |
| // Realbox. |
| {"searchBoxHint", IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD}, |
| {"realboxSeparator", IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR}, |
| {"removeSuggestion", IDS_OMNIBOX_REMOVE_SUGGESTION}, |
| {"removeSuggestionA11ySuffix", IDS_ACC_REMOVE_SUGGESTION_SUFFIX}, |
| {"removeSuggestionA11yPrefix", IDS_ACC_REMOVE_SUGGESTION_FOCUSED_PREFIX}, |
| {"hideSuggestions", IDS_TOOLTIP_HEADER_HIDE_SUGGESTIONS_BUTTON}, |
| {"showSuggestions", IDS_TOOLTIP_HEADER_SHOW_SUGGESTIONS_BUTTON}, |
| {"hideSection", IDS_ACC_HEADER_HIDE_SUGGESTIONS_BUTTON}, |
| {"showSection", IDS_ACC_HEADER_SHOW_SUGGESTIONS_BUTTON}, |
| |
| // Logo/doodle. |
| {"copyLink", IDS_NTP_DOODLE_SHARE_DIALOG_COPY_LABEL}, |
| {"doodleLink", IDS_NTP_DOODLE_SHARE_DIALOG_LINK_LABEL}, |
| {"email", IDS_NTP_DOODLE_SHARE_DIALOG_MAIL_LABEL}, |
| {"facebook", IDS_NTP_DOODLE_SHARE_DIALOG_FACEBOOK_LABEL}, |
| {"shareDoodle", IDS_NTP_DOODLE_SHARE_LABEL}, |
| {"twitter", IDS_NTP_DOODLE_SHARE_DIALOG_TWITTER_LABEL}, |
| |
| // Theme. |
| {"themeCreatedBy", IDS_NEW_TAB_ATTRIBUTION_INTRO}, |
| |
| // Modules. |
| {"dismissModuleToastMessage", IDS_NTP_MODULES_DISMISS_TOAST_MESSAGE}, |
| {"moduleInfoButtonTitle", IDS_NTP_MODULES_INFO_BUTTON_TITLE}, |
| {"moduleDismissButtonTitle", IDS_NTP_MODULES_DISMISS_BUTTON_TITLE}, |
| {"modulesDriveTitle", IDS_NTP_MODULES_DRIVE_TITLE}, |
| {"modulesDummyTitle", IDS_NTP_MODULES_DUMMY_TITLE}, |
| {"modulesDummy2Title", IDS_NTP_MODULES_DUMMY2_TITLE}, |
| {"modulesKaleidoscopeTitle", IDS_NTP_MODULES_KALEIDOSCOPE_TITLE}, |
| {"modulesTasksInfoTitle", IDS_NTP_MODULES_SHOPPING_TASKS_INFO_TITLE}, |
| {"modulesTasksInfoClose", IDS_NTP_MODULES_SHOPPING_TASKS_INFO_CLOSE}, |
| {"modulesCartHeaderNew", IDS_NTP_MODULES_CART_HEADER_CHIP_NEW}, |
| {"modulesCartTitle", IDS_NTP_MODULES_CART_TITLE}, |
| {"modulesCartWarmWelcome", IDS_NTP_MODULES_CART_WARM_WELCOME}, |
| {"modulesCartModuleMenuHide", IDS_NTP_MODULES_CART_MODULE_MENU_HIDE}, |
| {"modulesCartModuleMenuHideToastMessage", |
| IDS_NTP_MODULES_CART_MODULE_MENU_HIDE_TOAST_MESSAGE}, |
| {"modulesCartModuleMenuRemove", IDS_NTP_MODULES_CART_MODULE_MENU_REMOVE}, |
| {"modulesCartModuleMenuRemoveToastMessage", |
| IDS_NTP_MODULES_CART_MODULE_MENU_REMOVE_TOAST_MESSAGE}, |
| {"modulesCartCartMenuHideMerchant", |
| IDS_NTP_MODULES_CART_CART_MENU_HIDE_MERCHANT}, |
| {"modulesCartCartMenuHideMerchantToastMessage", |
| IDS_NTP_MODULES_CART_CART_MENU_HIDE_MERCHANT_TOAST_MESSAGE}, |
| {"modulesCartCartMenuRemoveMerchant", |
| IDS_NTP_MODULES_CART_CART_MENU_REMOVE_MERCHANT}, |
| {"modulesCartCartMenuRemoveMerchantToastMessage", |
| IDS_NTP_MODULES_CART_CART_MENU_REMOVE_MERCHANT_TOAST_MESSAGE}, |
| }; |
| AddLocalizedStringsBulk(source, kStrings); |
| |
| source->AddString("modulesTasksInfo1", |
| l10n_util::GetStringFUTF16( |
| IDS_NTP_MODULES_SHOPPING_TASKS_INFO_1, |
| base::UTF8ToUTF16("https://myactivity.google.com/"))); |
| source->AddString("modulesTasksInfo2", |
| l10n_util::GetStringFUTF16( |
| IDS_NTP_MODULES_SHOPPING_TASKS_INFO_2, |
| base::UTF8ToUTF16("https://policies.google.com/"))); |
| |
| // Register images that are purposefully not inlined in the HTML and instead |
| // are set in Javascript. |
| static constexpr webui::ResourcePath kImages[] = { |
| {omnibox::kGoogleGIconResourceName, |
| IDR_WEBUI_IMAGES_200_LOGO_GOOGLEG_PNG}, |
| {omnibox::kBookmarkIconResourceName, IDR_LOCAL_NTP_ICONS_BOOKMARK}, |
| {omnibox::kCalculatorIconResourceName, IDR_LOCAL_NTP_ICONS_CALCULATOR}, |
| {omnibox::kClockIconResourceName, IDR_LOCAL_NTP_ICONS_CLOCK}, |
| {omnibox::kDriveDocsIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_DOCS}, |
| {omnibox::kDriveFolderIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_FOLDER}, |
| {omnibox::kDriveFormIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_FORM}, |
| {omnibox::kDriveImageIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_IMAGE}, |
| {omnibox::kDriveLogoIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_LOGO}, |
| {omnibox::kDrivePdfIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_PDF}, |
| {omnibox::kDriveSheetsIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_SHEETS}, |
| {omnibox::kDriveSlidesIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_SLIDES}, |
| {omnibox::kDriveVideoIconResourceName, IDR_LOCAL_NTP_ICONS_DRIVE_VIDEO}, |
| {omnibox::kExtensionAppIconResourceName, |
| IDR_LOCAL_NTP_ICONS_EXTENSION_APP}, |
| {omnibox::kPageIconResourceName, IDR_LOCAL_NTP_ICONS_PAGE}, |
| {omnibox::kSearchIconResourceName, IDR_WEBUI_IMAGES_ICON_SEARCH_SVG}, |
| {omnibox::kTrendingUpIconResourceName, IDR_LOCAL_NTP_ICONS_TRENDING_UP}}; |
| webui::AddResourcePathsBulk(source, kImages); |
| |
| source->AddBoolean( |
| "recipeTasksModuleEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kNtpRecipeTasksModule)); |
| source->AddBoolean( |
| "shoppingTasksModuleEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kNtpShoppingTasksModule)); |
| source->AddBoolean( |
| "chromeCartModuleEnabled", |
| base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule)); |
| source->AddBoolean("driveModuleEnabled", base::FeatureList::IsEnabled( |
| ntp_features::kNtpDriveModule)); |
| |
| webui::SetupWebUIDataSource( |
| source, base::make_span(kNewTabPageResources, kNewTabPageResourcesSize), |
| IDR_NEW_TAB_PAGE_NEW_TAB_PAGE_HTML); |
| |
| // Allows creating <script> and inlining as well as network requests to |
| // support inlining the OneGoogleBar. |
| // TODO(crbug.com/1076506): remove when changing to iframed OneGoogleBar. |
| // Needs to happen after |webui::SetupWebUIDataSource()| since also overrides |
| // script-src. |
| source->OverrideContentSecurityPolicy( |
| network::mojom::CSPDirectiveName::ScriptSrc, |
| "script-src chrome://resources chrome://test " |
| "'self' 'unsafe-inline' https:;"); |
| // Allow embedding of iframes from the One Google Bar and |
| // chrome-untrusted://new-tab-page for other external content and resources. |
| source->OverrideContentSecurityPolicy( |
| network::mojom::CSPDirectiveName::ChildSrc, |
| base::StringPrintf("child-src https: %s %s;", |
| google_util::CommandLineGoogleBaseURL().spec().c_str(), |
| chrome::kChromeUIUntrustedNewTabPageUrl)); |
| |
| return source; |
| } |
| |
| } // namespace |
| |
| NewTabPageUI::NewTabPageUI(content::WebUI* web_ui) |
| : ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/false), |
| content::WebContentsObserver(web_ui->GetWebContents()), |
| page_factory_receiver_(this), |
| customize_themes_factory_receiver_(this), |
| profile_(Profile::FromWebUI(web_ui)), |
| instant_service_(InstantServiceFactory::GetForProfile(profile_)), |
| web_contents_(web_ui->GetWebContents()), |
| // We initialize navigation_start_time_ to a reasonable value to account |
| // for the unlikely case where the NewTabPageHandler is created before we |
| // received the DidStartNavigation event. |
| navigation_start_time_(base::Time::Now()) { |
| auto* source = CreateNewTabPageUiHtmlSource(profile_); |
| source->AddBoolean("customBackgroundDisabledByPolicy", |
| instant_service_->IsCustomBackgroundDisabledByPolicy()); |
| source->AddBoolean( |
| "modulesVisibleManagedByPolicy", |
| profile_->GetPrefs()->IsManagedPreference(prefs::kNtpModulesVisible)); |
| content::WebUIDataSource::Add(profile_, source); |
| |
| content::URLDataSource::Add(profile_, |
| std::make_unique<SanitizedImageSource>(profile_)); |
| content::URLDataSource::Add( |
| profile_, std::make_unique<FaviconSource>( |
| profile_, chrome::FaviconUrlFormat::kFavicon2)); |
| content::URLDataSource::Add(profile_, |
| std::make_unique<UntrustedSource>(profile_)); |
| content::URLDataSource::Add( |
| profile_, |
| std::make_unique<ThemeSource>(profile_, /*serve_untrusted=*/true)); |
| |
| web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme); |
| |
| instant_service_->AddObserver(this); |
| instant_service_->UpdateNtpTheme(); |
| } |
| |
| WEB_UI_CONTROLLER_TYPE_IMPL(NewTabPageUI) |
| |
| NewTabPageUI::~NewTabPageUI() { |
| instant_service_->RemoveObserver(this); |
| } |
| |
| // static |
| bool NewTabPageUI::IsNewTabPageOrigin(const GURL& url) { |
| return url.GetOrigin() == GURL(chrome::kChromeUINewTabPageURL).GetOrigin(); |
| } |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<new_tab_page::mojom::PageHandlerFactory> |
| pending_receiver) { |
| if (page_factory_receiver_.is_bound()) { |
| page_factory_receiver_.reset(); |
| } |
| |
| page_factory_receiver_.Bind(std::move(pending_receiver)); |
| } |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<promo_browser_command::mojom::CommandHandler> |
| pending_page_handler) { |
| promo_browser_command_handler_ = std::make_unique<PromoBrowserCommandHandler>( |
| std::move(pending_page_handler), profile_); |
| } |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver< |
| customize_themes::mojom::CustomizeThemesHandlerFactory> |
| pending_receiver) { |
| if (customize_themes_factory_receiver_.is_bound()) { |
| customize_themes_factory_receiver_.reset(); |
| } |
| customize_themes_factory_receiver_.Bind(std::move(pending_receiver)); |
| } |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<task_module::mojom::TaskModuleHandler> |
| pending_receiver) { |
| task_module_handler_ = std::make_unique<TaskModuleHandler>( |
| std::move(pending_receiver), profile_); |
| } |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<drive::mojom::DriveHandler> pending_receiver) { |
| drive_handler_ = std::make_unique<DriveHandler>(std::move(pending_receiver)); |
| } |
| |
| #if !defined(OFFICIAL_BUILD) |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<foo::mojom::FooHandler> pending_page_handler) { |
| foo_handler_ = std::make_unique<FooHandler>(std::move(pending_page_handler)); |
| } |
| #endif |
| |
| void NewTabPageUI::BindInterface( |
| mojo::PendingReceiver<chrome_cart::mojom::CartHandler> |
| pending_page_handler) { |
| cart_handler_ = |
| std::make_unique<CartHandler>(std::move(pending_page_handler), profile_); |
| } |
| |
| void NewTabPageUI::CreatePageHandler( |
| mojo::PendingRemote<new_tab_page::mojom::Page> pending_page, |
| mojo::PendingReceiver<new_tab_page::mojom::PageHandler> |
| pending_page_handler) { |
| DCHECK(pending_page.is_valid()); |
| page_handler_ = std::make_unique<NewTabPageHandler>( |
| std::move(pending_page_handler), std::move(pending_page), profile_, |
| instant_service_, web_contents_, |
| navigation_start_time_); |
| } |
| |
| void NewTabPageUI::CreateCustomizeThemesHandler( |
| mojo::PendingRemote<customize_themes::mojom::CustomizeThemesClient> |
| pending_client, |
| mojo::PendingReceiver<customize_themes::mojom::CustomizeThemesHandler> |
| pending_handler) { |
| customize_themes_handler_ = std::make_unique<ChromeCustomizeThemesHandler>( |
| std::move(pending_client), std::move(pending_handler), web_contents_, |
| profile_); |
| } |
| |
| void NewTabPageUI::NtpThemeChanged(const NtpTheme& theme) { |
| // Load time data is cached across page reloads. Update the background color |
| // here to prevent a white flicker on page reload. |
| UpdateBackgroundColor(theme); |
| } |
| |
| void NewTabPageUI::MostVisitedInfoChanged(const InstantMostVisitedInfo& info) {} |
| |
| void NewTabPageUI::DidStartNavigation( |
| content::NavigationHandle* navigation_handle) { |
| if (navigation_handle->IsInMainFrame()) { |
| navigation_start_time_ = base::Time::Now(); |
| } |
| } |
| |
| void NewTabPageUI::UpdateBackgroundColor(const NtpTheme& theme) { |
| std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue); |
| auto background_color = theme.background_color; |
| update->SetString( |
| "backgroundColor", |
| base::StringPrintf("#%02X%02X%02X", SkColorGetR(background_color), |
| SkColorGetG(background_color), |
| SkColorGetB(background_color))); |
| url::RawCanonOutputT<char> encoded_url; |
| url::EncodeURIComponent(theme.custom_background_url.spec().c_str(), |
| theme.custom_background_url.spec().size(), |
| &encoded_url); |
| update->SetString("backgroundImageUrl", |
| std::string(encoded_url.data(), encoded_url.length())); |
| content::WebUIDataSource::Update(profile_, chrome::kChromeUINewTabPageHost, |
| std::move(update)); |
| } |