Remove chrome://welcome code
Fixed: 338999420 Bug: 40253961 Change-Id: I51730bfd76eb4538ad1a63877b43bcfd4e6bc418 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6054055 Commit-Queue: Nicolas Dossou-Gbété <dgn@chromium.org> Reviewed-by: John Lee <johntlee@chromium.org> Reviewed-by: Chris Mullins <crmullins@chromium.org> Auto-Submit: Nicolas Dossou-Gbété <dgn@chromium.org> Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org> Reviewed-by: Alex Ilin <alexilin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1391586}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
d1c19e4c9f
commit
a05c6dab32
chrome
app
browser
chrome_content_browser_client.cc
chrome_paks.gnipolicy
resources
BUILD.gn
welcome
BUILD.gnOWNERSlanding_view.csslanding_view.html.tslanding_view.tslanding_view_proxy.tsnavigation_mixin.ts
google_apps
google_app_proxy.tsgoogle_apps_metrics_proxy.tsnux_google_apps.cssnux_google_apps.html.tsnux_google_apps.ts
images
background_svgs
ntp_background
ntp_background_metrics_proxy.tsntp_background_proxy.tsnux_ntp_background.cssnux_ntp_background.html.tsnux_ntp_background.ts
router.tsset_as_default
shared
action_link_style.cssanimations.cssbookmark_proxy.tschooser_shared.cssicons.htmlmodule_metrics_proxy.tsnavi_colors.cssnux_types.tsonboarding_background.cssonboarding_background.html.tsonboarding_background.tssplash_pages_shared.cssstep_indicator.cssstep_indicator.html.tsstep_indicator.ts
signin_view.csssignin_view.html.tssignin_view.tssignin_view_proxy.tswelcome.csswelcome.htmlwelcome_app.csswelcome_app.html.tswelcome_app.tswelcome_browser_proxy.tssearch
background
search_engine_choice
sessions
ui
BUILD.gn
privacy_sandbox
startup
webui
chrome_url_data_manager_browsertest.ccchrome_web_ui_configs.ccchrome_web_ui_controller_factory.cc
welcome
DEPSDIR_METADATAOWNERSbookmark_handler.ccbookmark_handler.hbookmark_item.ccbookmark_item.hgoogle_apps_handler.ccgoogle_apps_handler.hhelpers.cchelpers.hntp_background_fetcher.ccntp_background_fetcher.hntp_background_handler.ccntp_background_handler.hset_as_default_handler.ccset_as_default_handler.hwelcome_handler.ccwelcome_handler.hwelcome_ui.ccwelcome_ui.h
common
test
BUILD.gn
data
webui
BUILD.gn
welcome
BUILD.gnapp_chooser_test.tsmodule_metrics_test.tsnavigation_mixin_test.tsnux_ntp_background_test.tsnux_set_as_default_test.tssignin_view_test.tstest_bookmark_proxy.tstest_google_app_proxy.tstest_landing_view_proxy.tstest_metrics_proxy.tstest_ntp_background_proxy.tstest_nux_set_as_default_proxy.tstest_signin_view_proxy.tstest_welcome_browser_proxy.tswelcome_app_test.tswelcome_browsertest.cc
third_party/lit/v3_0
tools
@ -25,8 +25,6 @@ per-file media_router_strings.grdp=file://chrome/browser/media/router/OWNERS
|
||||
|
||||
per-file nearby_share_strings.grdp=file://chrome/browser/nearby_sharing/OWNERS
|
||||
|
||||
per-file welcome_strings.grdp=file://chrome/browser/ui/webui/welcome/OWNERS
|
||||
|
||||
per-file printing_strings.grdp=file://printing/OWNERS
|
||||
|
||||
per-file profiles_strings.grdp=file://chrome/app/profiles_strings_grdp/OWNERS
|
||||
|
@ -334,11 +334,6 @@ are declared in tools/grit/grit_rule.gni.
|
||||
<part file="nearby_share_strings.grdp" />
|
||||
</if>
|
||||
|
||||
<!-- Welcome strings -->
|
||||
<if expr="not chromeos_ash and not is_android">
|
||||
<part file="welcome_strings.grdp" />
|
||||
</if>
|
||||
|
||||
<!-- What's New strings -->
|
||||
<if expr="not is_android">
|
||||
<part file="whats_new_strings.grdp" />
|
||||
|
@ -1,127 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<grit-part>
|
||||
<!-- Shared strings -->
|
||||
<message name="IDS_WELCOME_NEXT" desc="Label for a button to confirm and continue from the current welcome step.">
|
||||
Next
|
||||
</message>
|
||||
<message name="IDS_WELCOME_SKIP" desc="Label for a button to skip the current welcome step.">
|
||||
Skip
|
||||
</message>
|
||||
<message name="IDS_WELCOME_STEPS" desc="Label indicating what step the user is in and how many steps there are in total.">
|
||||
Step <ph name="CURRENT_STEP">$1<ex>1</ex></ph> of <ph name="TOTAL_STEPS">$2<ex>2</ex></ph>
|
||||
</message>
|
||||
<message name="IDS_WELCOME_BOOKMARK_ADDED" desc="String read for accessibility to inform the user a bookmark was added.">
|
||||
Bookmark added
|
||||
</message>
|
||||
<message name="IDS_WELCOME_BOOKMARKS_ADDED" desc="String read for accessibility to inform the user that several bookmarks were added.">
|
||||
Bookmarks added
|
||||
</message>
|
||||
<message name="IDS_WELCOME_BOOKMARK_REMOVED" desc="String read for accessibility to inform the user a bookmark was removed.">
|
||||
Bookmark removed
|
||||
</message>
|
||||
<message name="IDS_WELCOME_BOOKMARKS_REMOVED" desc="String read for accessibility to inform the user that several bookmarks were removed.">
|
||||
Bookmarks removed
|
||||
</message>
|
||||
<message name="IDS_DEFAULT_BROWSER_CHANGED" desc="text notifying users that their default browser is successfully changed to Chrome">
|
||||
Chrome is your default browser
|
||||
</message>
|
||||
|
||||
<!-- Google apps selection module -->
|
||||
<message name="IDS_WELCOME_GOOGLE_APPS_DESCRIPTION" desc="Description of what this section does in the welcome workflow. This section lets a user bookmark popular Google apps.">
|
||||
Add bookmarks to your favorite Google Apps
|
||||
</message>
|
||||
<if expr="_google_chrome">
|
||||
<message name="IDS_WELCOME_GOOGLE_SEARCH" desc="Label for a button that creates a bookmark to google.com, this should be the name of the brand.">
|
||||
Google
|
||||
</message>
|
||||
</if>
|
||||
<message name="IDS_WELCOME_GOOGLE_GMAIL" desc="Label for a button that creates a bookmark to gmail.com, this should be the name of the brand.">
|
||||
Gmail
|
||||
</message>
|
||||
<message name="IDS_WELCOME_GOOGLE_APPS_MAPS" desc="Label for a button that creates a bookmark to maps.google.com, this should be the name of the brand.">
|
||||
Maps
|
||||
</message>
|
||||
<message name="IDS_WELCOME_GOOGLE_APPS_NEWS" desc="Label for a button that creates a bookmark to news.google.com, this should be the name of the brand.">
|
||||
News
|
||||
</message>
|
||||
<message name="IDS_WELCOME_GOOGLE_APPS_TRANSLATE" desc="Label for a button that creates a bookmark to translate.google.com, this should be the name of the brand.">
|
||||
Translate
|
||||
</message>
|
||||
<message name="IDS_WELCOME_GOOGLE_APPS_YOUTUBE" desc="Label for a button that creates a bookmark to youtube.com, this should be the name of the brand.">
|
||||
YouTube
|
||||
</message>
|
||||
|
||||
<!-- NTP background selection module -->
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_DESCRIPTION" desc="Description of what this section does in the welcome workflow. This section lets a user change the background for the New Tab Page">
|
||||
Pick a background
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_DEFAULT_TITLE" desc="Label for the default option when selecting a background. The default is to not have a background.">
|
||||
Default
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_ART_TITLE" desc="Label for choosing a background/wallpaper from the 'Art' category">
|
||||
Art
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_LANDSCAPE_TITLE" desc="Label for choosing a background/wallpaper from the 'Landscape' category, as in a category of photos of scenery and large outdoor spaces.">
|
||||
Landscape
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_CITYSCAPE_TITLE" desc="Label for choosing a background/wallpaper from the 'Cityscape' category">
|
||||
Cityscape
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_EARTH_TITLE" desc="Label for choosing a background/wallpaper from the 'Earth' category, as in a category of photos of planets and outer space.">
|
||||
Earth
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_GEOMETRIC_SHAPES_TITLE" desc="Label for choosing a background/wallpaper from the 'Geometric Shapes' category">
|
||||
Geometric shapes
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_PHOTO_BY_LABEL" desc="Label indicating who the background/wallpaper is created or photographed by">
|
||||
Photo by <ph name="NAME">$1<ex>John Doe</ex></ph>
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED" desc="String read for accessibility to inform the user that the background of the New Tab Page (referred to as 'start page') has been changed to a specific photo.">
|
||||
Start page background has been changed to <ph name="CATEGORY">$1<ex>Geometric shapes</ex></ph>.
|
||||
</message>
|
||||
<message name="IDS_WELCOME_NTP_BACKGROUND_RESET" desc="String read for accessibility to inform the user that the background of the New Tab Page (referred to as 'start page') has been reset to the default background.">
|
||||
Start page background has been reset to the default background.
|
||||
</message>
|
||||
|
||||
<!-- set default module -->
|
||||
<message name="IDS_WELCOME_SET_AS_DEFAULT_HEADER" desc="Header for the page that prompts user to set Chrome as their default browser.">
|
||||
Set Chrome as your default browser
|
||||
</message>
|
||||
<message name="IDS_WELCOME_SET_AS_DEFAULT_SUB_HEADER" desc="Sub-header for the page that prompts user to set Chrome as their default browser.">
|
||||
Get Google Search and Google smarts everytime you browse
|
||||
</message>
|
||||
<message name="IDS_WELCOME_SET_AS_DEFAULT_SET_AS_DEFAULT" desc="The label for a button to confirm setting Chrome as their default browser.">
|
||||
Set as default
|
||||
</message>
|
||||
|
||||
<!-- Landing view -->
|
||||
<message name="IDS_WELCOME_LANDING_TITLE" desc="Title for the page that prompts user to start setting up their new Chrome.">
|
||||
Make Chrome your own
|
||||
</message>
|
||||
<message name="IDS_WELCOME_LANDING_DESCRIPTION" desc="Description for the page that prompts user to start setting up their new Chrome.">
|
||||
Set up your browser in a few simple steps
|
||||
</message>
|
||||
<message name="IDS_WELCOME_LANDING_NEW_USER" desc="Label for a button that prompts new users to start setting up their new Chrome.">
|
||||
Get Started
|
||||
</message>
|
||||
<message name="IDS_WELCOME_LANDING_EXISTING_USER" desc="Label for a button that prompts existing users to sign in.">
|
||||
Already a Chrome user? Sign in
|
||||
</message>
|
||||
<message name="IDS_WELCOME_LANDING_PAUSE_ANIMATIONS" desc="Label for a button that pauses all animations on the page.">
|
||||
Pause animations
|
||||
</message>
|
||||
<message name="IDS_WELCOME_LANDING_PLAY_ANIMATIONS" desc="Label for a button that plays all animations on the page.">
|
||||
Play animations
|
||||
</message>
|
||||
|
||||
<!-- Sign-in view -->
|
||||
<message name="IDS_WELCOME_SIGNIN_VIEW_HEADER" desc="Header for the page that prompts user to sign in to chrome.">
|
||||
Your Chrome, Everywhere
|
||||
</message>
|
||||
<message name="IDS_WELCOME_SIGNIN_VIEW_SUB_HEADER" desc="Sub-header for the page that prompts user to sign in to chrome.">
|
||||
Sign in and turn on sync to get your bookmarks, passwords and more on all devices
|
||||
</message>
|
||||
<message name="IDS_WELCOME_SIGNIN_VIEW_SIGNIN" desc="The label for a button to let users sign in to chrome.">
|
||||
Continue
|
||||
</message>
|
||||
</grit-part>
|
@ -1 +0,0 @@
|
||||
fe9e961d86153df4d4f8a7e92f48565772a94ef6
|
@ -1 +0,0 @@
|
||||
15dd13f96e49e4c620235ca4122eff08a60a7c53
|
@ -1 +0,0 @@
|
||||
ab7212da9244c6ba7da1bea1cff337dce99c54f9
|
@ -7294,16 +7294,6 @@ bool ChromeContentBrowserClient::HandleWebUI(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// TODO(crbug.com/40647483): Remove when issue is resolved.
|
||||
if (url->SchemeIs(content::kChromeUIScheme) &&
|
||||
url->host() == chrome::kChromeUIWelcomeWin10Host) {
|
||||
*url =
|
||||
ReplaceURLHostAndPath(*url, chrome::kChromeUIWelcomeHost, url->path());
|
||||
return true;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
|
||||
browser_context, *url) &&
|
||||
!content::WebUIConfigMap::GetInstance().GetConfig(browser_context,
|
||||
@ -7362,16 +7352,6 @@ bool ChromeContentBrowserClient::ShowPaymentHandlerWindow(
|
||||
bool ChromeContentBrowserClient::HandleWebUIReverse(
|
||||
GURL* url,
|
||||
content::BrowserContext* browser_context) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// TODO(crbug.com/40647483): Remove when issue is resolved.
|
||||
// No need to actually reverse-rewrite the URL, but return true to update the
|
||||
// displayed URL when rewriting chrome://welcome-win10 to chrome://welcome.
|
||||
if (url->SchemeIs(content::kChromeUIScheme) &&
|
||||
url->host() == chrome::kChromeUIWelcomeHost) {
|
||||
return true;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
#if BUILDFLAG(CHROME_ROOT_STORE_CERT_MANAGEMENT_UI)
|
||||
// No need to actually reverse-rewrite the URL, but return true to update the
|
||||
// displayed URL when rewriting chrome://settings/certificates to
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
||||
#include "chrome/browser/ui/ui_features.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/browser/ui/webui/whats_new/whats_new_ui.h"
|
||||
#include "chrome/browser/ui/webui/whats_new/whats_new_util.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
@ -61,7 +60,6 @@ class PromotionalTabsEnabledPolicyTest
|
||||
PromotionalTabsEnabledPolicyTest() {
|
||||
const std::vector<base::test::FeatureRef> kEnabledFeatures = {
|
||||
whats_new::kForceEnabled,
|
||||
welcome::kForceEnabled,
|
||||
};
|
||||
scoped_feature_list_.InitWithFeatures(kEnabledFeatures, {});
|
||||
}
|
||||
@ -108,48 +106,6 @@ class PromotionalTabsEnabledPolicyTest
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
// Tests that the PromotionalTabsEnabled policy properly suppresses the welcome
|
||||
// page for browser first-runs.
|
||||
class PromotionalTabsEnabledPolicyWelcomeTest
|
||||
: public PromotionalTabsEnabledPolicyTest {
|
||||
public:
|
||||
PromotionalTabsEnabledPolicyWelcomeTest(
|
||||
const PromotionalTabsEnabledPolicyWelcomeTest&) = delete;
|
||||
PromotionalTabsEnabledPolicyWelcomeTest& operator=(
|
||||
const PromotionalTabsEnabledPolicyWelcomeTest&) = delete;
|
||||
|
||||
protected:
|
||||
PromotionalTabsEnabledPolicyWelcomeTest() = default;
|
||||
|
||||
void SetUpCommandLine(base::CommandLine* command_line) override {
|
||||
command_line->AppendSwitch(switches::kForceFirstRun);
|
||||
}
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(PromotionalTabsEnabledPolicyWelcomeTest, RunTest) {
|
||||
TabStripModel* tab_strip = browser()->tab_strip_model();
|
||||
ASSERT_GE(tab_strip->count(), 1);
|
||||
const auto& url = tab_strip->GetWebContentsAt(0)->GetLastCommittedURL();
|
||||
|
||||
// Only the NTP should show, regardless of the policy state.
|
||||
EXPECT_EQ(tab_strip->count(), 1);
|
||||
if (url.possibly_invalid_spec() != chrome::kChromeUINewTabURL) {
|
||||
EXPECT_PRED2(search::IsNTPOrRelatedURL, url, browser()->profile());
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
All,
|
||||
PromotionalTabsEnabledPolicyWelcomeTest,
|
||||
testing::ValuesIn(std::vector<std::pair<PolicyTest::BooleanPolicy,
|
||||
PolicyTest::BooleanPolicy>>{
|
||||
{PolicyTest::BooleanPolicy::kNotConfigured,
|
||||
PolicyTest::BooleanPolicy::kNotConfigured},
|
||||
{PolicyTest::BooleanPolicy::kFalse, PolicyTest::BooleanPolicy::kFalse},
|
||||
{PolicyTest::BooleanPolicy::kTrue, PolicyTest::BooleanPolicy::kTrue},
|
||||
{PolicyTest::BooleanPolicy::kFalse,
|
||||
PolicyTest::BooleanPolicy::kTrue}}));
|
||||
|
||||
// Tests that the PromotionalTabsEnabled policy properly suppresses the What's
|
||||
// New page.
|
||||
class PromotionalTabsEnabledPolicyWhatsNewTest
|
||||
@ -175,12 +131,8 @@ class PromotionalTabsEnabledPolicyWhatsNewTest
|
||||
base::FilePath user_data_dir;
|
||||
base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
||||
|
||||
// Suppress the welcome page by setting the pref indicating that it has
|
||||
// already been seen. This is necessary because welcome/onboarding takes
|
||||
// precedence over What's New.
|
||||
std::string json;
|
||||
base::Value::Dict prefs;
|
||||
prefs.SetByDottedPath(prefs::kHasSeenWelcomePage, true);
|
||||
// Set the session startup pref to NewTab. This enables consistent test
|
||||
// expectations across platforms - we should always expect to see the NTP.
|
||||
// Without this line, on ChromeOS only, the default type is LAST, which
|
||||
@ -293,8 +245,7 @@ IN_PROC_BROWSER_TEST_P(PromotionalTabsEnabledPolicyWhatsNewInvalidTest,
|
||||
const auto& url = tab_strip->GetWebContentsAt(0)->GetLastCommittedURL();
|
||||
|
||||
// Only the NTP should show. There are no other relevant tabs since
|
||||
// welcome and What's New have both already been shown or promotional tabs
|
||||
// are disabled.
|
||||
// What's New has already been shown or promotional tabs are disabled.
|
||||
EXPECT_EQ(tab_strip->count(), 1);
|
||||
if (url.possibly_invalid_spec() != chrome::kChromeUINewTabURL) {
|
||||
EXPECT_PRED2(search::IsNTPOrRelatedURL, url, browser()->profile());
|
||||
|
@ -123,7 +123,6 @@ group("resources") {
|
||||
public_deps += [
|
||||
"inline_login:resources",
|
||||
"signin/profile_picker:resources",
|
||||
"welcome:resources",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1,128 +0,0 @@
|
||||
# Copyright 2018 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//chrome/common/features.gni")
|
||||
import("//ui/webui/resources/tools/build_webui.gni")
|
||||
import("//ui/webui/resources/tools/generate_grd.gni")
|
||||
|
||||
assert(!is_chromeos_ash && !is_android)
|
||||
|
||||
if (is_chrome_branded) {
|
||||
generate_grd("build_icons_grdp") {
|
||||
grd_prefix = "welcome_images"
|
||||
out_grd = "$target_gen_dir/icon_resources.grdp"
|
||||
input_files = [
|
||||
"module_icons/add_bookmarks.svg",
|
||||
"module_icons/pick_a_background.svg",
|
||||
"module_icons/set_default_dark.svg",
|
||||
"module_icons/set_default_light.svg",
|
||||
"ntp_thumbnails/art.jpg",
|
||||
"ntp_thumbnails/cityscape.jpg",
|
||||
"ntp_thumbnails/earth.jpg",
|
||||
"ntp_thumbnails/geometric_shapes.jpg",
|
||||
"ntp_thumbnails/landscape.jpg",
|
||||
"set_default_dark.svg",
|
||||
"set_default_light.svg",
|
||||
]
|
||||
input_files_base_dir =
|
||||
rebase_path("//chrome/app/theme/google_chrome/welcome/", "//")
|
||||
resource_path_prefix = "images"
|
||||
}
|
||||
}
|
||||
|
||||
build_webui("build") {
|
||||
grd_prefix = "welcome"
|
||||
|
||||
static_files = [
|
||||
"images/background_svgs/bookmarks_background.svg",
|
||||
"images/background_svgs/bookmarks_foreground.svg",
|
||||
"images/background_svgs/devices_check.svg",
|
||||
"images/background_svgs/devices.svg",
|
||||
"images/background_svgs/hexagon.svg",
|
||||
"images/background_svgs/lozenge.svg",
|
||||
"images/background_svgs/password_field.svg",
|
||||
"images/background_svgs/password.svg",
|
||||
"images/background_svgs/square.svg",
|
||||
"images/background_svgs/streamer_circle.svg",
|
||||
"images/background_svgs/streamer_line.svg",
|
||||
"images/background_svgs/triangle.svg",
|
||||
"welcome.html",
|
||||
"welcome.css",
|
||||
]
|
||||
|
||||
if (is_chrome_branded) {
|
||||
# Additional static files that need to be passed separately since they have
|
||||
# a different |input_files_base_dir|
|
||||
extra_grdp_deps = [ ":build_icons_grdp" ]
|
||||
extra_grdp_files = [ "$target_gen_dir/icon_resources.grdp" ]
|
||||
}
|
||||
|
||||
non_web_component_files = [
|
||||
"landing_view.html.ts",
|
||||
"landing_view_proxy.ts",
|
||||
"landing_view.ts",
|
||||
"navigation_mixin.ts",
|
||||
"router.ts",
|
||||
"signin_view.html.ts",
|
||||
"signin_view_proxy.ts",
|
||||
"signin_view.ts",
|
||||
"welcome_app.html.ts",
|
||||
"welcome_app.ts",
|
||||
"welcome_browser_proxy.ts",
|
||||
|
||||
"google_apps/google_app_proxy.ts",
|
||||
"google_apps/google_apps_metrics_proxy.ts",
|
||||
"google_apps/nux_google_apps.html.ts",
|
||||
"google_apps/nux_google_apps.ts",
|
||||
"ntp_background/ntp_background_metrics_proxy.ts",
|
||||
"ntp_background/ntp_background_proxy.ts",
|
||||
"ntp_background/nux_ntp_background.html.ts",
|
||||
"ntp_background/nux_ntp_background.ts",
|
||||
"set_as_default/nux_set_as_default.html.ts",
|
||||
"set_as_default/nux_set_as_default_proxy.ts",
|
||||
"set_as_default/nux_set_as_default.ts",
|
||||
"shared/bookmark_proxy.ts",
|
||||
"shared/module_metrics_proxy.ts",
|
||||
"shared/nux_types.ts",
|
||||
"shared/onboarding_background.html.ts",
|
||||
"shared/onboarding_background.ts",
|
||||
"shared/step_indicator.html.ts",
|
||||
"shared/step_indicator.ts",
|
||||
]
|
||||
|
||||
# Files that are passed as input to css_to_wrapper().
|
||||
css_files = [
|
||||
"google_apps/nux_google_apps.css",
|
||||
"landing_view.css",
|
||||
"ntp_background/nux_ntp_background.css",
|
||||
"set_as_default/nux_set_as_default.css",
|
||||
"shared/action_link_style.css",
|
||||
"shared/animations.css",
|
||||
"shared/chooser_shared.css",
|
||||
"shared/navi_colors.css",
|
||||
"shared/onboarding_background.css",
|
||||
"shared/splash_pages_shared.css",
|
||||
"shared/step_indicator.css",
|
||||
"signin_view.css",
|
||||
"welcome_app.css",
|
||||
]
|
||||
|
||||
icons_html_files = [ "shared/icons.html" ]
|
||||
|
||||
ts_composite = true
|
||||
ts_definitions = [
|
||||
"//tools/typescript/definitions/bookmarks.d.ts",
|
||||
"//tools/typescript/definitions/chrome_event.d.ts",
|
||||
"//tools/typescript/definitions/chrome_send.d.ts",
|
||||
"//tools/typescript/definitions/metrics_private.d.ts",
|
||||
]
|
||||
ts_deps = [
|
||||
"//third_party/lit/v3_0:build_ts",
|
||||
"//ui/webui/resources/cr_elements:build_ts",
|
||||
"//ui/webui/resources/js:build_ts",
|
||||
]
|
||||
|
||||
html_to_wrapper_template = "detect"
|
||||
webui_context_type = "trusted"
|
||||
}
|
@ -1 +0,0 @@
|
||||
johntlee@chromium.org
|
@ -1,61 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {sendWithPromise} from 'chrome://resources/js/cr.js';
|
||||
|
||||
import type {BookmarkListItem} from '../shared/nux_types.js';
|
||||
|
||||
enum NuxGoogleAppsSelections {
|
||||
GMAIL_DEPRECATED = 0,
|
||||
YOU_TUBE,
|
||||
MAPS,
|
||||
TRANSLATE,
|
||||
NEWS,
|
||||
CHROME_WEB_STORE,
|
||||
}
|
||||
|
||||
export interface GoogleAppProxy {
|
||||
/**
|
||||
* Google app IDs are local to the list of Google apps, so their icon must
|
||||
* be cached by the handler that provided the IDs.
|
||||
*/
|
||||
cacheBookmarkIcon(appId: number): void;
|
||||
|
||||
/**
|
||||
* Returns a promise for an array of Google apps.
|
||||
*/
|
||||
getAppList(): Promise<BookmarkListItem[]>;
|
||||
|
||||
/**
|
||||
* @param providerId This should match one of the histogram enum
|
||||
* value for NuxGoogleAppsSelections.
|
||||
*/
|
||||
recordProviderSelected(providerId: number): void;
|
||||
}
|
||||
|
||||
export class GoogleAppProxyImpl implements GoogleAppProxy {
|
||||
cacheBookmarkIcon(appId: number) {
|
||||
chrome.send('cacheGoogleAppIcon', [appId]);
|
||||
}
|
||||
|
||||
getAppList() {
|
||||
return sendWithPromise('getGoogleAppsList');
|
||||
}
|
||||
|
||||
recordProviderSelected(providerId: number) {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
'FirstRun.NewUserExperience.GoogleAppsSelection', providerId,
|
||||
Object.keys(NuxGoogleAppsSelections).length);
|
||||
}
|
||||
|
||||
static getInstance(): GoogleAppProxy {
|
||||
return instance || (instance = new GoogleAppProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: GoogleAppProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: GoogleAppProxy|null = null;
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import type {ModuleMetricsProxy} from '../shared/module_metrics_proxy.js';
|
||||
import {ModuleMetricsProxyImpl, NuxGoogleAppsInteractions} from '../shared/module_metrics_proxy.js';
|
||||
|
||||
export class GoogleAppsMetricsProxyImpl extends ModuleMetricsProxyImpl {
|
||||
constructor() {
|
||||
super(
|
||||
'FirstRun.NewUserExperience.GoogleAppsInteraction',
|
||||
NuxGoogleAppsInteractions);
|
||||
}
|
||||
|
||||
static getInstance(): ModuleMetricsProxy {
|
||||
return instance || (instance = new GoogleAppsMetricsProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: ModuleMetricsProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: ModuleMetricsProxy|null = null;
|
@ -1,164 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #import=../shared/animations.css.js
|
||||
* #import=../shared/chooser_shared.css.js
|
||||
* #include=animations chooser-shared
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
.apps-ask {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.chrome-logo {
|
||||
background-image: url(../images/module_icons/add_bookmarks.svg);
|
||||
background-position: center bottom;
|
||||
background-size: 170px 170px;
|
||||
height: 146px;
|
||||
margin: auto;
|
||||
margin-bottom: 32px;
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--cr-primary-text-color);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
margin-bottom: 48px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#appChooser {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.button-bar {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.option {
|
||||
-webkit-appearance: none;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
font-family: inherit;
|
||||
height: 7.5rem;
|
||||
justify-content: center;
|
||||
outline: 0;
|
||||
position: relative;
|
||||
transition-duration: 500ms;
|
||||
transition-property: box-shadow;
|
||||
vertical-align: bottom;
|
||||
width: 6.25rem;
|
||||
}
|
||||
|
||||
.option:not(:first-of-type) {
|
||||
margin-inline-start: 1.5rem;
|
||||
}
|
||||
|
||||
.option[active] {
|
||||
border: 1px solid var(--cr-checked-color);
|
||||
color: var(--cr-checked-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.option.keyboard-focused:focus {
|
||||
outline: var(--navi-keyboard-focus-color) solid 3px;
|
||||
}
|
||||
|
||||
.option-name {
|
||||
flex-grow: 0;
|
||||
line-height: 1.25rem;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.option-icon {
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
height: 2rem;
|
||||
margin: auto;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.option-icon-shadow {
|
||||
background-color: var(--navi-option-icon-shadow-color);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
height: 3rem;
|
||||
margin-bottom: .25rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.option cr-icon {
|
||||
--iron-icon-fill-color: var(--cr-card-background-color);
|
||||
background: var(--navi-check-icon-color);
|
||||
border-radius: 50%;
|
||||
display: none;
|
||||
height: .75rem;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: .375rem;
|
||||
top: .375rem;
|
||||
width: .75rem;
|
||||
}
|
||||
|
||||
:host-context([dir=rtl]) .option cr-icon {
|
||||
left: .375rem;
|
||||
right: unset;
|
||||
}
|
||||
|
||||
.option.keyboard-focused:focus cr-icon[icon='cr:check'],
|
||||
.option:hover cr-icon[icon='cr:check'],
|
||||
.option[active] cr-icon[icon='cr:check'] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.option[active] cr-icon[icon='cr:check'] {
|
||||
background: var(--cr-checked-color);
|
||||
}
|
||||
|
||||
/* App Icons */
|
||||
.gmail {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_GMAIL@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_GMAIL@2x) 2x);
|
||||
}
|
||||
|
||||
.youtube {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_YOUTUBE@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_YOUTUBE@2x) 2x);
|
||||
}
|
||||
|
||||
.maps {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_MAPS@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_MAPS@2x) 2x);
|
||||
}
|
||||
|
||||
.translate {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_TRANSLATE@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_TRANSLATE@2x) 2x);
|
||||
}
|
||||
|
||||
.news {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_NEWS@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_NEWS@2x) 2x);
|
||||
}
|
||||
|
||||
.search {
|
||||
content: image-set(
|
||||
url(chrome://theme/IDS_WELCOME_SEARCH@1x) 1x,
|
||||
url(chrome://theme/IDS_WELCOME_SEARCH@2x) 2x);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {NuxGoogleAppsElement} from './nux_google_apps.js';
|
||||
|
||||
export function getHtml(this: NuxGoogleAppsElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div class="apps-ask">
|
||||
<div class="chrome-logo" aria-hidden="true"></div>
|
||||
<h1 tabindex="-1">${this.subtitle}</h1>
|
||||
<div id="appChooser">
|
||||
<div class="slide-in">
|
||||
${this.appList_.map((item, index) => html`
|
||||
<button ?active="${item.selected}"
|
||||
aria-pressed="${item.selected}"
|
||||
data-index="${index}" @click="${this.onAppClick_}"
|
||||
@pointerdown="${this.onAppPointerDown_}"
|
||||
@keyup="${this.onAppKeyUp_}" class="option">
|
||||
<div class="option-icon-shadow">
|
||||
<div class="${item.icon} option-icon"></div>
|
||||
</div>
|
||||
<div class="option-name">${item.name}</div>
|
||||
<cr-icon icon="cr:check"></cr-icon>
|
||||
</button>
|
||||
`)}
|
||||
</div>
|
||||
|
||||
<div class="button-bar">
|
||||
<cr-button id="noThanksButton" @click="${this.onNoThanksClicked_}">
|
||||
$i18n{skip}
|
||||
</cr-button>
|
||||
<step-indicator .model="${this.indicatorModel}"></step-indicator>
|
||||
<cr-button class="action-button" ?disabled="${!this.hasAppsSelected_}"
|
||||
@click="${this.onNextClicked_}">
|
||||
$i18n{next}
|
||||
<cr-icon icon="cr:chevron-right"></cr-icon>
|
||||
</cr-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
|
||||
import 'chrome://resources/cr_elements/icons.html.js';
|
||||
import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
|
||||
import '../shared/step_indicator.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {getInstance as getAnnouncerInstance} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js';
|
||||
import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {isRTL} from 'chrome://resources/js/util.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {NavigationMixin} from '../navigation_mixin.js';
|
||||
import {navigateToNextStep} from '../router.js';
|
||||
import type {BookmarkProxy} from '../shared/bookmark_proxy.js';
|
||||
import {BookmarkBarManager, BookmarkProxyImpl} from '../shared/bookmark_proxy.js';
|
||||
import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
|
||||
import type {StepIndicatorModel} from '../shared/nux_types.js';
|
||||
|
||||
import type {GoogleAppProxy} from './google_app_proxy.js';
|
||||
import {GoogleAppProxyImpl} from './google_app_proxy.js';
|
||||
import {GoogleAppsMetricsProxyImpl} from './google_apps_metrics_proxy.js';
|
||||
import {getCss} from './nux_google_apps.css.js';
|
||||
import {getHtml} from './nux_google_apps.html.js';
|
||||
|
||||
interface AppItem {
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string;
|
||||
url: string;
|
||||
bookmarkId: string|null;
|
||||
selected: boolean;
|
||||
}
|
||||
|
||||
const KEYBOARD_FOCUSED = 'keyboard-focused';
|
||||
|
||||
export interface NuxGoogleAppsElement {
|
||||
$: {
|
||||
noThanksButton: HTMLElement,
|
||||
};
|
||||
}
|
||||
|
||||
const NuxGoogleAppsElementBase = I18nMixinLit(NavigationMixin(CrLitElement));
|
||||
|
||||
export class NuxGoogleAppsElement extends NuxGoogleAppsElementBase {
|
||||
static get is() {
|
||||
return 'nux-google-apps';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
indicatorModel: {type: Object},
|
||||
appList_: {type: Array},
|
||||
hasAppsSelected_: {type: Boolean},
|
||||
};
|
||||
}
|
||||
|
||||
private appProxy_: GoogleAppProxy;
|
||||
private metricsManager_: ModuleMetricsManager;
|
||||
private finalized_: boolean = false;
|
||||
private bookmarkProxy_: BookmarkProxy;
|
||||
private bookmarkBarManager_: BookmarkBarManager;
|
||||
private wasBookmarkBarShownOnInit_: boolean = false;
|
||||
protected appList_: AppItem[] = [];
|
||||
protected hasAppsSelected_: boolean = true;
|
||||
indicatorModel?: StepIndicatorModel;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.subtitle = loadTimeData.getString('googleAppsDescription');
|
||||
this.appProxy_ = GoogleAppProxyImpl.getInstance();
|
||||
this.metricsManager_ =
|
||||
new ModuleMetricsManager(GoogleAppsMetricsProxyImpl.getInstance());
|
||||
this.bookmarkProxy_ = BookmarkProxyImpl.getInstance();
|
||||
this.bookmarkBarManager_ = BookmarkBarManager.getInstance();
|
||||
}
|
||||
|
||||
override onRouteEnter() {
|
||||
this.finalized_ = false;
|
||||
this.metricsManager_.recordPageInitialized();
|
||||
this.populateAllBookmarks_();
|
||||
}
|
||||
|
||||
override onRouteExit() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.cleanUp_();
|
||||
this.metricsManager_.recordBrowserBackOrForward();
|
||||
}
|
||||
|
||||
override onRouteUnload() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.cleanUp_();
|
||||
this.metricsManager_.recordNavigatedAway();
|
||||
}
|
||||
|
||||
private changeFocus_(element: EventTarget, direction: number) {
|
||||
if (isRTL()) {
|
||||
direction *= -1; // Reverse direction if RTL.
|
||||
}
|
||||
|
||||
const buttons = this.shadowRoot!.querySelectorAll('button');
|
||||
const targetIndex = Array.prototype.indexOf.call(buttons, element);
|
||||
|
||||
const oldFocus = buttons[targetIndex];
|
||||
if (!oldFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newFocus = buttons[targetIndex + direction];
|
||||
|
||||
// New target and we're changing direction.
|
||||
if (newFocus && direction) {
|
||||
newFocus.classList.add(KEYBOARD_FOCUSED);
|
||||
oldFocus.classList.remove(KEYBOARD_FOCUSED);
|
||||
newFocus.focus();
|
||||
} else {
|
||||
oldFocus.classList.add(KEYBOARD_FOCUSED);
|
||||
}
|
||||
}
|
||||
|
||||
private announceA11y_(text: string) {
|
||||
getAnnouncerInstance().announce(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when bookmarks should be removed for all selected apps.
|
||||
*/
|
||||
private cleanUp_() {
|
||||
this.finalized_ = true;
|
||||
|
||||
if (this.appList_.length === 0) {
|
||||
return;
|
||||
} // No apps to remove.
|
||||
|
||||
let removedBookmarks = false;
|
||||
this.appList_.forEach(app => {
|
||||
if (app.selected && app.bookmarkId) {
|
||||
// Don't call |updateBookmark_| b/c we want to save the selection in the
|
||||
// event of a browser back/forward.
|
||||
this.bookmarkProxy_.removeBookmark(app.bookmarkId);
|
||||
app.bookmarkId = null;
|
||||
removedBookmarks = true;
|
||||
}
|
||||
});
|
||||
// Only update and announce if we removed bookmarks.
|
||||
if (removedBookmarks) {
|
||||
this.bookmarkBarManager_.setShown(this.wasBookmarkBarShownOnInit_);
|
||||
this.announceA11y_(this.i18n('bookmarksRemoved'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle toggling the apps selected.
|
||||
*/
|
||||
protected onAppClick_(e: Event) {
|
||||
const index = Number((e.currentTarget as HTMLElement).dataset['index']);
|
||||
const item = this.appList_[index]!;
|
||||
|
||||
item.selected = !item.selected;
|
||||
this.requestUpdate();
|
||||
|
||||
this.updateBookmark_(item);
|
||||
this.updateHasAppsSelected_();
|
||||
|
||||
this.metricsManager_.recordClickedOption();
|
||||
|
||||
// Announcements should NOT be in |updateBookmark_| because there should be
|
||||
// a different utterance when all app bookmarks are added/removed.
|
||||
const i18nKey = item.selected ? 'bookmarkAdded' : 'bookmarkRemoved';
|
||||
this.announceA11y_(this.i18n(i18nKey));
|
||||
}
|
||||
|
||||
protected onAppKeyUp_(e: KeyboardEvent) {
|
||||
if (e.key === 'ArrowRight') {
|
||||
this.changeFocus_(e.currentTarget!, 1);
|
||||
} else if (e.key === 'ArrowLeft') {
|
||||
this.changeFocus_(e.currentTarget!, -1);
|
||||
} else {
|
||||
(e.currentTarget as HTMLElement).classList.add(KEYBOARD_FOCUSED);
|
||||
}
|
||||
}
|
||||
|
||||
protected onAppPointerDown_(e: Event) {
|
||||
(e.currentTarget as HTMLElement).classList.remove(KEYBOARD_FOCUSED);
|
||||
}
|
||||
|
||||
protected onNextClicked_() {
|
||||
this.finalized_ = true;
|
||||
this.appList_.forEach(app => {
|
||||
if (app.selected) {
|
||||
this.appProxy_.recordProviderSelected(app.id);
|
||||
}
|
||||
});
|
||||
this.metricsManager_.recordGetStarted();
|
||||
navigateToNextStep();
|
||||
}
|
||||
|
||||
protected onNoThanksClicked_() {
|
||||
this.cleanUp_();
|
||||
this.metricsManager_.recordNoThanks();
|
||||
navigateToNextStep();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when bookmarks should be created for all selected apps.
|
||||
*/
|
||||
private populateAllBookmarks_() {
|
||||
this.wasBookmarkBarShownOnInit_ = this.bookmarkBarManager_.getShown();
|
||||
|
||||
if (this.appList_.length > 0) {
|
||||
this.appList_.forEach(app => this.updateBookmark_(app));
|
||||
} else {
|
||||
this.appProxy_.getAppList().then(list => {
|
||||
this.appList_ = list as AppItem[];
|
||||
this.appList_.forEach((app, index) => {
|
||||
// Default select first few items.
|
||||
app.selected = index < 3;
|
||||
this.updateBookmark_(app);
|
||||
});
|
||||
this.updateHasAppsSelected_();
|
||||
this.announceA11y_(this.i18n('bookmarksAdded'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateBookmark_(item: AppItem) {
|
||||
if (item.selected && !item.bookmarkId) {
|
||||
this.bookmarkBarManager_.setShown(true);
|
||||
this.bookmarkProxy_
|
||||
.addBookmark({
|
||||
title: item.name,
|
||||
url: item.url,
|
||||
parentId: '1',
|
||||
})
|
||||
.then(result => {
|
||||
item.bookmarkId = result.id;
|
||||
});
|
||||
// Cache bookmark icon.
|
||||
this.appProxy_.cacheBookmarkIcon(item.id);
|
||||
} else if (!item.selected && item.bookmarkId) {
|
||||
this.bookmarkProxy_.removeBookmark(item.bookmarkId);
|
||||
item.bookmarkId = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value of hasAppsSelected_.
|
||||
*/
|
||||
private updateHasAppsSelected_() {
|
||||
this.hasAppsSelected_ = this.appList_.some(a => a.selected);
|
||||
if (!this.hasAppsSelected_) {
|
||||
this.bookmarkBarManager_.setShown(this.wasBookmarkBarShownOnInit_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'nux-google-apps': NuxGoogleAppsElement;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(NuxGoogleAppsElement.is, NuxGoogleAppsElement);
|
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M243.157 281.451h-86.314a17.677 17.677 0 0 1-17.658-17.657V141.061a17.677 17.677 0 0 1 17.658-17.658h86.314a17.677 17.677 0 0 1 17.657 17.658v122.733a17.677 17.677 0 0 1-17.657 17.657zm-86.314-152.048a11.67 11.67 0 0 0-11.658 11.658v122.733a11.67 11.67 0 0 0 11.658 11.657h86.314a11.67 11.67 0 0 0 11.657-11.657V141.061a11.67 11.67 0 0 0-11.657-11.658zm80.864 73.024a3 3 0 0 0-3-3H188.22a3 3 0 1 0 0 6h46.487a3 3 0 0 0 3-3zm0 20.807a3 3 0 0 0-3-3H188.22a3 3 0 0 0 0 6h46.487a3 3 0 0 0 3-3zm0 20.805a3 3 0 0 0-3-3H188.22a3 3 0 1 0 0 6h46.487a3 3 0 0 0 3-3z"/></svg>
|
Before (image error) Size: 635 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="m180.515 170.398 13.067 7.868v-56.717h-26.134v56.717l13.067-7.868z"/><circle cx="167.435" cy="202.427" r="5.374"/><circle cx="167.435" cy="223.233" r="5.374"/><circle cx="167.435" cy="244.04" r="5.374"/></svg>
|
Before (image error) Size: 280 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M321.707 326.399H151.065a3 3 0 0 1 0-6h170.642a3 3 0 0 1 0 6zM119.89 76.601a5.425 5.425 0 0 1 5.426 5.425v94.582a5.425 5.425 0 0 1-5.425 5.426H83.719a5.425 5.425 0 0 1-5.426-5.426V82.026a5.425 5.425 0 0 1 5.426-5.425h36.172m0-5H83.719a10.437 10.437 0 0 0-10.426 10.425v94.582a10.437 10.437 0 0 0 10.426 10.426h36.172a10.437 10.437 0 0 0 10.425-10.426V82.026a10.437 10.437 0 0 0-10.425-10.425zM305.524 313.26H167.248a8.12 8.12 0 0 1-8.111-8.111v-86.535a8.12 8.12 0 0 1 8.11-8.111h138.277a8.12 8.12 0 0 1 8.111 8.11v86.535a8.12 8.12 0 0 1-8.11 8.112zm-138.276-96.757a2.113 2.113 0 0 0-2.111 2.11v86.535a2.114 2.114 0 0 0 2.111 2.112h138.276a2.114 2.114 0 0 0 2.111-2.112v-86.534a2.113 2.113 0 0 0-2.11-2.111z" fill="#dadce0"/></svg>
|
Before (image error) Size: 801 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M96.806 141.625a2.99 2.99 0 0 1-2.12-.878l-8.62-8.619a3 3 0 1 1 4.243-4.242l6.497 6.497 16.495-16.494a3 3 0 0 1 4.242 4.242l-18.616 18.616a2.99 2.99 0 0 1-2.12.878zm129.879 141.321a2.991 2.991 0 0 1-2.122-.879l-16.726-16.726a3 3 0 0 1 4.242-4.243l14.606 14.605 34.008-34.008a3 3 0 0 1 4.242 4.243l-36.13 36.129a2.99 2.99 0 0 1-2.12.879z" fill="#3982f8"/></svg>
|
Before (image error) Size: 431 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="72.78" height="64.77" viewBox="0 0 72.78 64.77"><path fill="#FBBC04" d="M51.36 0H21.45C19.14 0 17 1.23 15.84 3.24L.88 29.15c-1.16 2-1.16 4.47 0 6.48l14.96 25.91c1.16 2 3.29 3.24 5.61 3.24h29.91c2.31 0 4.45-1.23 5.61-3.24l14.96-25.91c1.16-2 1.16-4.47 0-6.48L56.97 3.24A6.451 6.451 0 0 0 51.36 0z"/></svg>
|
Before (image error) Size: 350 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M178.022 178.022a21.978 21.978 0 0 0 0 43.956h43.956a21.978 21.978 0 0 0 0-43.956z"/></svg>
|
Before (image error) Size: 162 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><circle cx="133.729" cy="200" r="9.136" fill="#34a853"/><circle cx="166.865" cy="200" r="9.136" fill="#34a853"/><circle cx="200" cy="200" r="9.136" fill="#34a853"/><circle cx="233.135" cy="200" r="9.136" fill="#34a853"/><circle cx="266.271" cy="200" r="9.136" fill="#34a853"/></svg>
|
Before (image error) Size: 344 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M320.592 167.441h-8.856v-8.245a13.743 13.743 0 1 0-27.486 0v8.245h-8.856a6.194 6.194 0 0 0-6.186 6.187v15.811l-186.796.001a9.2 9.2 0 0 0-9.19 9.19v46.727a9.2 9.2 0 0 0 9.19 9.19h209.39a9.189 9.189 0 0 0 9.19-9.19v-30.435h19.6a6.193 6.193 0 0 0 6.186-6.187v-35.108a6.192 6.192 0 0 0-6.186-6.186zm-30.342-8.245a7.743 7.743 0 1 1 15.486 0v8.245H290.25zm4.743 86.16a3.19 3.19 0 0 1-3.19 3.19H82.413a3.193 3.193 0 0 1-3.19-3.19V198.63a3.193 3.193 0 0 1 3.19-3.19h186.795v13.295a6.194 6.194 0 0 0 6.186 6.187h19.599zm25.785-36.621a.187.187 0 0 1-.186.186h-45.198a.187.187 0 0 1-.186-.186v-35.107a.187.187 0 0 1 .186-.187h45.198a.186.186 0 0 1 .186.186z"/></svg>
|
Before (image error) Size: 726 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><rect x="175" y="175" width="50" height="50" rx="5" fill="#fbbc04"/></svg>
|
Before (image error) Size: 136 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="M200.042 279.438H200a3.025 3.025 0 0 1-3.03-3 2.975 2.975 0 0 1 2.971-3h.101a3 3 0 1 1 0 6zm19.682-2.568a3 3 0 0 1-.769-5.9 3.04 3.04 0 0 1 3.715 2.107 2.958 2.958 0 0 1-2.06 3.66l-.114.031a3.023 3.023 0 0 1-.772.102zm-39.461-.004a3.008 3.008 0 0 1-.791-.107l-.056-.015a3 3 0 1 1 1.496-5.81l.138.037a3 3 0 0 1-.787 5.895zm57.901-7.62a3 3 0 0 1-1.482-5.61 3.043 3.043 0 0 1 4.122 1.087 2.958 2.958 0 0 1-1.04 4.062 8.256 8.256 0 0 1-.123.071 2.99 2.99 0 0 1-1.477.39zm-76.345-.01a2.986 2.986 0 0 1-1.514-.412l1.517-2.588-1.565 2.56a3 3 0 1 1 2.959-5.22 7.9 7.9 0 0 1 .124.072 3 3 0 0 1-1.52 5.588zm92.172-12.127a3 3 0 0 1-2.12-5.121 3.043 3.043 0 0 1 4.276-.036 2.957 2.957 0 0 1 .036 4.207l-.07.07a2.99 2.99 0 0 1-2.122.88zm-108.051-.036a2.909 2.909 0 0 1-2.07-.861l-.07-.07a3 3 0 0 1 4.243-4.242 3.018 3.018 0 0 1-2.103 5.174zm120.224-15.772a3.001 3.001 0 0 1-2.597-4.499 3.042 3.042 0 0 1 4.122-1.144 2.958 2.958 0 0 1 1.127 4.054l-.05.086a3 3 0 0 1-2.603 1.503zm-132.336-.018a3 3 0 0 1-2.603-1.503l2.6-1.498-2.638 1.431a3 3 0 1 1 5.176-3.034l.062.105a3.001 3.001 0 0 1-2.597 4.499zm140-18.423a3 3 0 0 1-2.912-3.701l.044-.169a3 3 0 0 1 5.789 1.58l-2.895-.79 2.886.821a3.024 3.024 0 0 1-2.912 2.259zm-147.7-.043a2.937 2.937 0 0 1-2.855-2.167c-.005-.024-.038-.144-.043-.168a3 3 0 0 1 5.826-1.435 3.043 3.043 0 0 1-2.148 3.67 3.113 3.113 0 0 1-.78.1zm150.31-19.717a3 3 0 0 1-3-3l.001-.065a3.342 3.342 0 0 1-.002-.1 3.043 3.043 0 0 1 3-3.05 2.958 2.958 0 0 1 3 2.95v.088l.001.077v.1a3 3 0 0 1-3 3zm-152.877-.066a2.958 2.958 0 0 1-3-2.95V200a3 3 0 0 1 6-.017 3.043 3.043 0 0 1-3 3.05zm2.565-19.732a3.005 3.005 0 0 1-2.897-3.79l2.895.79-2.886-.822a3 3 0 0 1 5.824 1.443c-.005.024-.038.144-.043.168a3.002 3.002 0 0 1-2.893 2.21zm147.71-.145a3.002 3.002 0 0 1-2.89-2.2l-.03-.108a3 3 0 0 1 5.79-1.579l-2.895.79 2.918-.705a3.003 3.003 0 0 1-2.893 3.802zm-140.102-18.351a2.919 2.919 0 0 1-1.463-.391 2.958 2.958 0 0 1-1.127-4.054l.05-.087a3 3 0 0 1 5.199 2.996 3.08 3.08 0 0 1-2.659 1.535zm132.453-.073a2.998 2.998 0 0 1-2.591-1.484l-.062-.105a3 3 0 0 1 5.2-2.996l-2.6 1.498 2.637-1.43a3 3 0 0 1-2.585 4.517zm-120.29-15.765a2.982 2.982 0 0 1-2.138-5.068l.07-.07a3 3 0 0 1 4.242 4.242 3.072 3.072 0 0 1-2.173.896zm108.124-.047a2.99 2.99 0 0 1-2.121-.879 3.042 3.042 0 0 1-.036-4.277 2.957 2.957 0 0 1 4.207-.035l.07.07a3 3 0 0 1-2.12 5.121zm-92.282-12.119a3.002 3.002 0 0 1-2.613-1.484 2.958 2.958 0 0 1 1.04-4.06c.012-.009.11-.066.123-.073a3 3 0 1 1 2.96 5.22 3.057 3.057 0 0 1-1.51.397zm76.435-.032a2.95 2.95 0 0 1-1.461-.387l-.087-.05a3 3 0 1 1 2.96-5.22l.06.035a3.007 3.007 0 0 1-1.472 5.622zm-57.99-7.616a3.029 3.029 0 0 1-2.933-2.209 2.958 2.958 0 0 1 2.06-3.66l.114-.032a3 3 0 0 1 1.541 5.8 3.042 3.042 0 0 1-.782.1zm39.574-.013a3.008 3.008 0 0 1-.79-.107 3.043 3.043 0 0 1-2.16-3.676 2.958 2.958 0 0 1 3.6-2.15l.138.037a3 3 0 0 1-.788 5.896zm-19.782-2.578a3.043 3.043 0 0 1-3.05-3 2.958 2.958 0 0 1 2.95-3h.1a3 3 0 0 1 0 6z"/></svg>
|
Before (image error) Size: 2.9 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 153.154 6.053"><circle cx="3.026" cy="3.026" r="3.026"/><circle cx="24.473" cy="3.026" r="3.026"/><circle cx="45.92" cy="3.026" r="3.026"/><circle cx="67.367" cy="3.026" r="3.026"/><circle cx="88.814" cy="3.026" r="3.026"/><circle cx="110.26" cy="3.026" r="3.026"/><circle cx="131.707" cy="3.026" r="3.026"/></svg>
|
Before (image error) Size: 367 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><path d="m197.439 173.536-28.851 49.97a2.957 2.957 0 0 0 2.561 4.437h57.702a2.957 2.957 0 0 0 2.561-4.436l-28.85-49.971a2.957 2.957 0 0 0-5.123 0z" fill="#34a853"/></svg>
|
Before (image error) Size: 232 B |
@ -1,26 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=./shared/animations.css.js
|
||||
* #import=./shared/splash_pages_shared.css.js
|
||||
* #import=./shared/action_link_style.css.js
|
||||
* #include=animations action-link-style splash-pages-shared
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
onboarding-background {
|
||||
--animation-delay: 275ms;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.action-button,
|
||||
.action-link {
|
||||
--animation-delay: 150ms;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {LandingViewElement} from './landing_view.js';
|
||||
|
||||
export function getHtml(this: LandingViewElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div id="container">
|
||||
<onboarding-background id="background" class="fade-in">
|
||||
</onboarding-background>
|
||||
<div id="text">
|
||||
<div class="header">
|
||||
<h1 class="fade-in" tabindex="-1">$i18n{landingTitle}</h1>
|
||||
<div class="subheading fade-in">$i18n{landingDescription}</div>
|
||||
</div>
|
||||
<cr-button class="action-button fade-in" @click="${this.onNewUserClick_}">
|
||||
$i18n{landingNewUser}
|
||||
</cr-button>
|
||||
<button class="action-link fade-in" @click="${this.onExistingUserClick_}">
|
||||
<span ?hidden="${!this.signinAllowed_}">$i18n{landingExistingUser}</span>
|
||||
<span ?hidden="${this.signinAllowed_}">$i18n{skip}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
|
||||
import './shared/action_link_style.css.js';
|
||||
import './shared/onboarding_background.js';
|
||||
import './shared/splash_pages_shared.css.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {getCss} from './landing_view.css.js';
|
||||
import {getHtml} from './landing_view.html.js';
|
||||
import type {LandingViewProxy} from './landing_view_proxy.js';
|
||||
import {LandingViewProxyImpl} from './landing_view_proxy.js';
|
||||
import {NavigationMixin} from './navigation_mixin.js';
|
||||
import {navigateTo, Routes} from './router.js';
|
||||
import type {OnboardingBackgroundElement} from './shared/onboarding_background.js';
|
||||
import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
|
||||
|
||||
export interface LandingViewElement {
|
||||
$: {
|
||||
background: OnboardingBackgroundElement,
|
||||
};
|
||||
}
|
||||
|
||||
const LandingViewElementBase = NavigationMixin(CrLitElement);
|
||||
|
||||
/** @polymer */
|
||||
export class LandingViewElement extends LandingViewElementBase {
|
||||
static get is() {
|
||||
return 'landing-view';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
signinAllowed_: {type: Boolean},
|
||||
};
|
||||
}
|
||||
|
||||
private landingViewProxy_: LandingViewProxy;
|
||||
private finalized_: boolean = false;
|
||||
protected signinAllowed_: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.landingViewProxy_ = LandingViewProxyImpl.getInstance();
|
||||
this.signinAllowed_ = loadTimeData.getBoolean('signinAllowed');
|
||||
}
|
||||
|
||||
override onRouteEnter() {
|
||||
this.finalized_ = false;
|
||||
this.landingViewProxy_.recordPageShown();
|
||||
this.$.background.play();
|
||||
}
|
||||
|
||||
override onRouteExit() {
|
||||
this.$.background.pause();
|
||||
}
|
||||
|
||||
override onRouteUnload() {
|
||||
// Clicking on 'Returning user' will change the URL.
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.finalized_ = true;
|
||||
this.landingViewProxy_.recordNavigatedAway();
|
||||
}
|
||||
|
||||
protected onExistingUserClick_() {
|
||||
this.finalized_ = true;
|
||||
this.landingViewProxy_.recordExistingUser();
|
||||
if (this.signinAllowed_) {
|
||||
WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn(
|
||||
'chrome://welcome/returning-user');
|
||||
} else {
|
||||
navigateTo(Routes.RETURNING_USER, 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected onNewUserClick_() {
|
||||
this.finalized_ = true;
|
||||
this.landingViewProxy_.recordNewUser();
|
||||
navigateTo(Routes.NEW_USER, 1);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(LandingViewElement.is, LandingViewElement);
|
@ -1,57 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
const NUX_LANDING_PAGE_INTERACTION_METRIC_NAME =
|
||||
'FirstRun.NewUserExperience.LandingPageInteraction';
|
||||
|
||||
enum NuxLandingPageInteractions {
|
||||
PAGE_SHOWN = 0,
|
||||
NAVIGATED_AWAY,
|
||||
NEW_USER,
|
||||
EXISTING_USER,
|
||||
}
|
||||
|
||||
const NUX_LANDING_PAGE_INTERACTIONS_COUNT =
|
||||
Object.keys(NuxLandingPageInteractions).length;
|
||||
|
||||
export interface LandingViewProxy {
|
||||
recordPageShown(): void;
|
||||
recordNavigatedAway(): void;
|
||||
recordNewUser(): void;
|
||||
recordExistingUser(): void;
|
||||
}
|
||||
|
||||
export class LandingViewProxyImpl implements LandingViewProxy {
|
||||
recordPageShown() {
|
||||
this.recordInteraction_(NuxLandingPageInteractions.PAGE_SHOWN);
|
||||
}
|
||||
|
||||
recordNavigatedAway() {
|
||||
this.recordInteraction_(NuxLandingPageInteractions.NAVIGATED_AWAY);
|
||||
}
|
||||
|
||||
recordNewUser() {
|
||||
this.recordInteraction_(NuxLandingPageInteractions.NEW_USER);
|
||||
}
|
||||
|
||||
recordExistingUser() {
|
||||
this.recordInteraction_(NuxLandingPageInteractions.EXISTING_USER);
|
||||
}
|
||||
|
||||
private recordInteraction_(interaction: number) {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
NUX_LANDING_PAGE_INTERACTION_METRIC_NAME, interaction,
|
||||
NUX_LANDING_PAGE_INTERACTIONS_COUNT);
|
||||
}
|
||||
|
||||
static getInstance(): LandingViewProxy {
|
||||
return instance || (instance = new LandingViewProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: LandingViewProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: LandingViewProxy|null = null;
|
@ -1,116 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* @fileoverview The NavigationMixin is in charge of manipulating and
|
||||
* watching window.history.state changes. The page is using the history
|
||||
* state object to remember state instead of changing the URL directly,
|
||||
* because the flow requires that users can use browser-back/forward to
|
||||
* navigate between steps, without being able to go directly or copy an URL
|
||||
* that points at a specific step. Using history.state object allows adding
|
||||
* or popping history state without actually changing the path.
|
||||
*/
|
||||
|
||||
import '/strings.m.js';
|
||||
|
||||
import {assert} from 'chrome://resources/js/assert.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import type {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {routeObservers, setCurrentRouteElement} from './router.js';
|
||||
import type {Routes} from './router.js';
|
||||
|
||||
type Constructor<T> = new (...args: any[]) => T;
|
||||
|
||||
/**
|
||||
* Elements can override onRoute(Change|Enter|Exit) to handle route changes.
|
||||
* Order of hooks being called:
|
||||
* 1) onRouteExit() on the old route
|
||||
* 2) onRouteChange() on all subscribed routes
|
||||
* 3) onRouteEnter() on the new route
|
||||
*/
|
||||
export const NavigationMixin =
|
||||
<T extends Constructor<CrLitElement>>(superClass: T): T&
|
||||
Constructor<NavigationMixinInterface> => {
|
||||
class NavigationMixin extends superClass {
|
||||
static get properties() {
|
||||
return {
|
||||
subtitle: String,
|
||||
};
|
||||
}
|
||||
|
||||
subtitle?: string;
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
assert(!routeObservers.has(this));
|
||||
routeObservers.add(this);
|
||||
const route = (history.state.route as Routes);
|
||||
const step = history.state.step;
|
||||
|
||||
// history state was set when page loaded, so when the element first
|
||||
// attaches, call the route-change handler to initialize first.
|
||||
this.onRouteChange(route, step);
|
||||
|
||||
// Modules are only attached to DOM if they're for the current route,
|
||||
// so as long as the id of an element matches up to the current step,
|
||||
// it means that element is for the current route.
|
||||
if (this.id === `step-${step}`) {
|
||||
setCurrentRouteElement(this);
|
||||
this.notifyRouteEnter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies elements that route was entered and updates the state of the
|
||||
* app based on the new route.
|
||||
*/
|
||||
notifyRouteEnter() {
|
||||
this.onRouteEnter();
|
||||
this.updateFocusForA11y();
|
||||
this.updateTitle();
|
||||
}
|
||||
|
||||
/** Called to update focus when progressing through the modules. */
|
||||
async updateFocusForA11y() {
|
||||
const header = this.shadowRoot!.querySelector('h1');
|
||||
if (header) {
|
||||
await this.updateComplete;
|
||||
header.focus();
|
||||
}
|
||||
}
|
||||
|
||||
updateTitle() {
|
||||
let title = loadTimeData.getString('headerText');
|
||||
if (this.subtitle) {
|
||||
title += ' - ' + this.subtitle;
|
||||
}
|
||||
document.title = title;
|
||||
}
|
||||
|
||||
override disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
assert(routeObservers.delete(this));
|
||||
}
|
||||
|
||||
onRouteChange(_route: Routes, _step: number) {}
|
||||
onRouteEnter() {}
|
||||
onRouteExit() {}
|
||||
onRouteUnload() {}
|
||||
}
|
||||
|
||||
return NavigationMixin;
|
||||
};
|
||||
|
||||
export interface NavigationMixinInterface {
|
||||
subtitle?: string;
|
||||
notifyRouteEnter(): void;
|
||||
updateFocusForA11y(): void;
|
||||
updateTitle(): void;
|
||||
onRouteChange(route: Routes, step: number): void;
|
||||
onRouteEnter(): void;
|
||||
onRouteExit(): void;
|
||||
onRouteUnload(): void;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import type {ModuleMetricsProxy} from '../shared/module_metrics_proxy.js';
|
||||
import {ModuleMetricsProxyImpl, NuxNtpBackgroundInteractions} from '../shared/module_metrics_proxy.js';
|
||||
|
||||
export class NtpBackgroundMetricsProxyImpl extends ModuleMetricsProxyImpl {
|
||||
constructor() {
|
||||
super(
|
||||
'FirstRun.NewUserExperience.NtpBackgroundInteraction',
|
||||
NuxNtpBackgroundInteractions);
|
||||
}
|
||||
|
||||
static getInstance(): ModuleMetricsProxy {
|
||||
return instance || (instance = new NtpBackgroundMetricsProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: ModuleMetricsProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: ModuleMetricsProxy|null = null;
|
@ -1,70 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {sendWithPromise} from 'chrome://resources/js/cr.js';
|
||||
|
||||
import {NuxNtpBackgroundInteractions} from '../shared/module_metrics_proxy.js';
|
||||
|
||||
export interface NtpBackgroundData {
|
||||
id: number;
|
||||
imageUrl: string;
|
||||
thumbnailClass: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface NtpBackgroundProxy {
|
||||
clearBackground(): void;
|
||||
getBackgrounds(): Promise<NtpBackgroundData[]>;
|
||||
preloadImage(url: string): Promise<void>;
|
||||
recordBackgroundImageFailedToLoad(): void;
|
||||
recordBackgroundImageNeverLoaded(): void;
|
||||
setBackground(id: number): void;
|
||||
}
|
||||
|
||||
export class NtpBackgroundProxyImpl implements NtpBackgroundProxy {
|
||||
clearBackground() {
|
||||
chrome.send('clearBackground');
|
||||
}
|
||||
|
||||
getBackgrounds() {
|
||||
return sendWithPromise('getBackgrounds');
|
||||
}
|
||||
|
||||
preloadImage(url: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const preloadedImage = new Image();
|
||||
preloadedImage.onerror = reject;
|
||||
preloadedImage.onload = () => resolve();
|
||||
preloadedImage.src = url;
|
||||
}) as Promise<void>;
|
||||
}
|
||||
|
||||
recordBackgroundImageFailedToLoad() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
'FirstRun.NewUserExperience.NtpBackgroundInteraction',
|
||||
NuxNtpBackgroundInteractions.BACKGROUND_IMAGE_FAILED_TO_LOAD,
|
||||
Object.keys(NuxNtpBackgroundInteractions).length);
|
||||
}
|
||||
|
||||
recordBackgroundImageNeverLoaded() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
'FirstRun.NewUserExperience.NtpBackgroundInteraction',
|
||||
NuxNtpBackgroundInteractions.BACKGROUND_IMAGE_NEVER_LOADED,
|
||||
Object.keys(NuxNtpBackgroundInteractions).length);
|
||||
}
|
||||
|
||||
setBackground(id: number) {
|
||||
chrome.send('setBackground', [id]);
|
||||
}
|
||||
|
||||
static getInstance(): NtpBackgroundProxy {
|
||||
return instance || (instance = new NtpBackgroundProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: NtpBackgroundProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: NtpBackgroundProxy|null = null;
|
@ -1,152 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #import=../shared/animations.css.js
|
||||
* #import=../shared/chooser_shared.css.js
|
||||
* #include=animations chooser-shared
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
:host {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#backgroundPreview {
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: background 300ms, opacity 400ms;
|
||||
}
|
||||
|
||||
#backgroundPreview.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#backgroundPreview::before {
|
||||
/* Copied from browser/resources/local_ntp/custom_backgrounds.js */
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .3));
|
||||
/* Pseudo element needs some content (even an empty string) to be
|
||||
* displayed. */
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
/* Put a non-static position on the content so that it can have a
|
||||
* higher stacking level than its previous sibling,
|
||||
* the #backgroundPreview element. */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ntp-background-logo {
|
||||
background-image: url(../images/module_icons/pick_a_background.svg);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 110px 110px;
|
||||
height: 110px;
|
||||
margin: auto;
|
||||
margin-bottom: 32px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--cr-primary-text-color);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
margin-bottom: 46px;
|
||||
outline: none;
|
||||
transition: color 400ms;
|
||||
}
|
||||
|
||||
#backgroundPreview.active + .content h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ntp-backgrounds-grid {
|
||||
display: grid;
|
||||
grid-gap: 32px;
|
||||
grid-template-columns: repeat(3, 176px);
|
||||
grid-template-rows: repeat(2, 176px);
|
||||
width: 592px;
|
||||
}
|
||||
|
||||
.option {
|
||||
align-items: stretch;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
text-align: start;
|
||||
transition: border-color 400ms, box-shadow 500ms;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#backgroundPreview.active + .content .option {
|
||||
border-color: var(--google-grey-700);
|
||||
}
|
||||
|
||||
/* Remove outline when button is focused using the mouse. */
|
||||
.option:focus:not(.keyboard-focused) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ntp-background-thumbnail {
|
||||
background-color: var(--cr-card-background-color);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.option-name {
|
||||
border-top: var(--cr-separator-line);
|
||||
color: var(--navi-wallpaper-text-color);
|
||||
height: 3rem;
|
||||
line-height: 3rem;
|
||||
overflow: hidden;
|
||||
padding: 0 .75rem;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.option[active] .option-name {
|
||||
background: var(--cr-checked-color);
|
||||
color: var(--cr-card-background-color);
|
||||
}
|
||||
|
||||
.button-bar {
|
||||
margin-top: 56px;
|
||||
}
|
||||
|
||||
/* Wallpaper Thumbnails */
|
||||
.art {
|
||||
background-image: url(../images/ntp_thumbnails/art.jpg);
|
||||
}
|
||||
|
||||
.cityscape {
|
||||
background-image: url(../images/ntp_thumbnails/cityscape.jpg);
|
||||
}
|
||||
|
||||
.earth {
|
||||
background-image: url(../images/ntp_thumbnails/earth.jpg);
|
||||
}
|
||||
|
||||
.geometric-shapes {
|
||||
background-image: url(../images/ntp_thumbnails/geometric_shapes.jpg);
|
||||
}
|
||||
|
||||
.landscape {
|
||||
background-image: url(../images/ntp_thumbnails/landscape.jpg);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {NuxNtpBackgroundElement} from './nux_ntp_background.js';
|
||||
|
||||
export function getHtml(this: NuxNtpBackgroundElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div id="backgroundPreview"
|
||||
@transitionend="${this.onBackgroundPreviewTransitionEnd_}">
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="ntp-background-logo" aria-hidden="true"></div>
|
||||
<h1 tabindex="-1">${this.subtitle}</h1>
|
||||
|
||||
<div class="ntp-backgrounds-grid slide-in">
|
||||
${this.backgrounds_.map((item, index) => html`
|
||||
<button
|
||||
?active="${this.isSelectedBackground_(item)}"
|
||||
class="option" data-index="${index}"
|
||||
@click="${this.onBackgroundClick_}"
|
||||
@keyup="${this.onBackgroundKeyUp_}"
|
||||
@pointerdown="${this.onBackgroundPointerDown_}">
|
||||
<div
|
||||
class="ntp-background-thumbnail ${item.thumbnailClass}">
|
||||
</div>
|
||||
<div class="option-name">${item.title}</div>
|
||||
</button>
|
||||
`)}
|
||||
</div>
|
||||
|
||||
<div class="button-bar">
|
||||
<cr-button id="skipButton" @click="${this.onSkipClicked_}">
|
||||
$i18n{skip}
|
||||
</cr-button>
|
||||
<step-indicator .model="${this.indicatorModel}"></step-indicator>
|
||||
<cr-button class="action-button" @click="${this.onNextClicked_}">
|
||||
$i18n{next}
|
||||
<cr-icon icon="cr:chevron-right"></cr-icon>
|
||||
</cr-button>
|
||||
</div>
|
||||
</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
|
||||
import 'chrome://resources/cr_elements/icons.html.js';
|
||||
import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
|
||||
import 'chrome://resources/js/cr.js';
|
||||
import '../shared/step_indicator.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {getInstance as getAnnouncerInstance} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js';
|
||||
import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {isRTL} from 'chrome://resources/js/util.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
import type {PropertyValues} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {NavigationMixin} from '../navigation_mixin.js';
|
||||
import {navigateToNextStep} from '../router.js';
|
||||
import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
|
||||
import type {StepIndicatorModel} from '../shared/nux_types.js';
|
||||
|
||||
import {NtpBackgroundMetricsProxyImpl} from './ntp_background_metrics_proxy.js';
|
||||
import type {NtpBackgroundData, NtpBackgroundProxy} from './ntp_background_proxy.js';
|
||||
import {NtpBackgroundProxyImpl} from './ntp_background_proxy.js';
|
||||
import {getCss} from './nux_ntp_background.css.js';
|
||||
import {getHtml} from './nux_ntp_background.html.js';
|
||||
|
||||
const KEYBOARD_FOCUSED_CLASS = 'keyboard-focused';
|
||||
|
||||
export interface NuxNtpBackgroundElement {
|
||||
$: {
|
||||
backgroundPreview: HTMLElement,
|
||||
skipButton: HTMLElement,
|
||||
};
|
||||
}
|
||||
|
||||
const NuxNtpBackgroundElementBase = I18nMixinLit(NavigationMixin(CrLitElement));
|
||||
|
||||
export class NuxNtpBackgroundElement extends NuxNtpBackgroundElementBase {
|
||||
static get is() {
|
||||
return 'nux-ntp-background';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
backgrounds_: {type: Array},
|
||||
selectedBackground_: {type: Object},
|
||||
indicatorModel: {type: Object},
|
||||
};
|
||||
}
|
||||
|
||||
protected backgrounds_: NtpBackgroundData[] = [];
|
||||
private selectedBackground_?: NtpBackgroundData;
|
||||
indicatorModel?: StepIndicatorModel;
|
||||
|
||||
private finalized_: boolean = false;
|
||||
private imageIsLoading_: boolean = false;
|
||||
|
||||
private metricsManager_: ModuleMetricsManager;
|
||||
private ntpBackgroundProxy_: NtpBackgroundProxy;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.subtitle = loadTimeData.getString('ntpBackgroundDescription');
|
||||
this.ntpBackgroundProxy_ = NtpBackgroundProxyImpl.getInstance();
|
||||
this.metricsManager_ =
|
||||
new ModuleMetricsManager(NtpBackgroundMetricsProxyImpl.getInstance());
|
||||
}
|
||||
|
||||
override updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
const changedPrivateProperties =
|
||||
changedProperties as Map<PropertyKey, unknown>;
|
||||
if (changedPrivateProperties.has('selectedBackground_')) {
|
||||
this.onSelectedBackgroundChange_();
|
||||
}
|
||||
}
|
||||
|
||||
override onRouteEnter() {
|
||||
this.finalized_ = false;
|
||||
const defaultBackground = {
|
||||
id: -1,
|
||||
imageUrl: '',
|
||||
thumbnailClass: '',
|
||||
title: this.i18n('ntpBackgroundDefault'),
|
||||
};
|
||||
if (!this.selectedBackground_) {
|
||||
this.selectedBackground_ = defaultBackground;
|
||||
}
|
||||
if (this.backgrounds_.length === 0) {
|
||||
this.ntpBackgroundProxy_.getBackgrounds().then((backgrounds) => {
|
||||
this.backgrounds_ = [
|
||||
defaultBackground,
|
||||
...backgrounds,
|
||||
];
|
||||
});
|
||||
}
|
||||
this.metricsManager_.recordPageInitialized();
|
||||
}
|
||||
|
||||
override onRouteExit() {
|
||||
if (this.imageIsLoading_) {
|
||||
this.ntpBackgroundProxy_.recordBackgroundImageNeverLoaded();
|
||||
}
|
||||
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.metricsManager_.recordBrowserBackOrForward();
|
||||
}
|
||||
|
||||
override onRouteUnload() {
|
||||
if (this.imageIsLoading_) {
|
||||
this.ntpBackgroundProxy_.recordBackgroundImageNeverLoaded();
|
||||
}
|
||||
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.metricsManager_.recordNavigatedAway();
|
||||
}
|
||||
|
||||
private hasValidSelectedBackground_(): boolean {
|
||||
return this.selectedBackground_!.id > -1;
|
||||
}
|
||||
|
||||
protected isSelectedBackground_(background: NtpBackgroundData) {
|
||||
return background === this.selectedBackground_;
|
||||
}
|
||||
|
||||
private onSelectedBackgroundChange_() {
|
||||
const id = this.selectedBackground_!.id;
|
||||
if (id > -1) {
|
||||
this.imageIsLoading_ = true;
|
||||
const imageUrl = this.selectedBackground_!.imageUrl;
|
||||
this.ntpBackgroundProxy_.preloadImage(imageUrl).then(
|
||||
() => {
|
||||
if (this.selectedBackground_!.id === id) {
|
||||
this.imageIsLoading_ = false;
|
||||
this.$.backgroundPreview.classList.add('active');
|
||||
this.$.backgroundPreview.style.backgroundImage =
|
||||
`url(${imageUrl})`;
|
||||
}
|
||||
},
|
||||
() => {
|
||||
this.ntpBackgroundProxy_.recordBackgroundImageFailedToLoad();
|
||||
});
|
||||
} else {
|
||||
this.$.backgroundPreview.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
protected onBackgroundPreviewTransitionEnd_() {
|
||||
// Whenever the #backgroundPreview transitions to a non-active, hidden
|
||||
// state, remove the background image. This way, when the element
|
||||
// transitions back to active, the previous background is not displayed.
|
||||
if (!this.$.backgroundPreview.classList.contains('active')) {
|
||||
this.$.backgroundPreview.style.backgroundImage = '';
|
||||
}
|
||||
}
|
||||
|
||||
private announceA11y_(text: string) {
|
||||
getAnnouncerInstance().announce(text);
|
||||
}
|
||||
|
||||
protected onBackgroundClick_(e: Event) {
|
||||
const index = Number((e.currentTarget as HTMLElement).dataset['index']);
|
||||
this.selectedBackground_ = this.backgrounds_[index]!;
|
||||
this.metricsManager_.recordClickedOption();
|
||||
this.announceA11y_(this.i18n(
|
||||
'ntpBackgroundPreviewUpdated', this.selectedBackground_.title));
|
||||
}
|
||||
|
||||
protected onBackgroundKeyUp_(e: KeyboardEvent) {
|
||||
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
|
||||
this.changeFocus_(e.currentTarget!, 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
|
||||
this.changeFocus_(e.currentTarget!, -1);
|
||||
} else {
|
||||
this.changeFocus_(e.currentTarget!, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private changeFocus_(element: EventTarget, direction: number) {
|
||||
if (isRTL()) {
|
||||
direction *= -1;
|
||||
}
|
||||
|
||||
// Reverse direction if RTL.
|
||||
const buttons =
|
||||
this.shadowRoot!.querySelectorAll<HTMLButtonElement>('.option');
|
||||
const targetIndex = Array.prototype.indexOf.call(buttons, element);
|
||||
|
||||
const oldFocus = buttons[targetIndex];
|
||||
if (!oldFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newFocus = buttons[targetIndex + direction];
|
||||
|
||||
if (newFocus && direction) {
|
||||
newFocus.classList.add(KEYBOARD_FOCUSED_CLASS);
|
||||
oldFocus.classList.remove(KEYBOARD_FOCUSED_CLASS);
|
||||
newFocus.focus();
|
||||
} else {
|
||||
oldFocus.classList.add(KEYBOARD_FOCUSED_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
protected onBackgroundPointerDown_(e: Event) {
|
||||
(e.currentTarget as HTMLElement).classList.remove(KEYBOARD_FOCUSED_CLASS);
|
||||
}
|
||||
|
||||
protected onNextClicked_() {
|
||||
this.finalized_ = true;
|
||||
|
||||
if (this.selectedBackground_ && this.selectedBackground_.id > -1) {
|
||||
this.ntpBackgroundProxy_.setBackground(this.selectedBackground_.id);
|
||||
} else {
|
||||
this.ntpBackgroundProxy_.clearBackground();
|
||||
}
|
||||
this.metricsManager_.recordGetStarted();
|
||||
navigateToNextStep();
|
||||
}
|
||||
|
||||
protected onSkipClicked_() {
|
||||
this.finalized_ = true;
|
||||
this.metricsManager_.recordNoThanks();
|
||||
navigateToNextStep();
|
||||
if (this.hasValidSelectedBackground_()) {
|
||||
this.announceA11y_(this.i18n('ntpBackgroundReset'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'nux-ntp-background': NuxNtpBackgroundElement;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(NuxNtpBackgroundElement.is, NuxNtpBackgroundElement);
|
@ -1,108 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {assert} from 'chrome://resources/js/assert.js';
|
||||
|
||||
import type {NavigationMixinInterface} from './navigation_mixin.js';
|
||||
|
||||
/**
|
||||
* Valid route pathnames.
|
||||
*/
|
||||
export enum Routes {
|
||||
LANDING = 'landing',
|
||||
NEW_USER = 'new-user',
|
||||
RETURNING_USER = 'returning-user'
|
||||
}
|
||||
|
||||
export const routeObservers: Set<NavigationMixinInterface> = new Set();
|
||||
|
||||
let currentRouteElement: NavigationMixinInterface|null;
|
||||
|
||||
export function setCurrentRouteElement(element: NavigationMixinInterface) {
|
||||
currentRouteElement = element;
|
||||
}
|
||||
|
||||
// Notifies all the elements that extended NavigationMixin.
|
||||
function notifyObservers() {
|
||||
if (currentRouteElement) {
|
||||
currentRouteElement.onRouteExit();
|
||||
currentRouteElement = null;
|
||||
}
|
||||
const route = (history.state.route as Routes);
|
||||
const step = history.state.step;
|
||||
routeObservers.forEach(observer => {
|
||||
observer.onRouteChange(route, step);
|
||||
|
||||
// Modules are only attached to DOM if they're for the current route, so
|
||||
// as long as the id of an element matches up to the current step, it
|
||||
// means that element is for the current route.
|
||||
if ((observer as unknown as HTMLElement).id === `step-${step}`) {
|
||||
currentRouteElement = observer;
|
||||
}
|
||||
});
|
||||
|
||||
// If currentRouteElement is not null, it means there was a new route.
|
||||
if (currentRouteElement) {
|
||||
(currentRouteElement as NavigationMixinInterface).notifyRouteEnter();
|
||||
}
|
||||
}
|
||||
|
||||
export function navigateToNextStep() {
|
||||
history.pushState(
|
||||
{route: history.state.route, step: history.state.step + 1}, '',
|
||||
`/${history.state.route}`);
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
export function navigateTo(route: Routes, step: number) {
|
||||
assert([
|
||||
Routes.LANDING,
|
||||
Routes.NEW_USER,
|
||||
Routes.RETURNING_USER,
|
||||
].includes(route));
|
||||
|
||||
history.pushState(
|
||||
{
|
||||
route: route,
|
||||
step: step,
|
||||
},
|
||||
'', '/' + (route === Routes.LANDING ? '' : route));
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
function main() {
|
||||
/**
|
||||
* Regular expression that captures the leading slash, the content and the
|
||||
* trailing slash in three different groups.
|
||||
*/
|
||||
const CANONICAL_PATH_REGEX: RegExp = /(^\/)([\/-\w]+)(\/$)/;
|
||||
const path = location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
|
||||
|
||||
// Sets up history state based on the url path, unless it's already set (e.g.
|
||||
// when user uses browser-back button to get back on chrome://welcome/...).
|
||||
if (!history.state || !history.state.route || !history.state.step) {
|
||||
switch (path) {
|
||||
case `/${Routes.NEW_USER}`:
|
||||
history.replaceState({route: Routes.NEW_USER, step: 1}, '', path);
|
||||
break;
|
||||
case `/${Routes.RETURNING_USER}`:
|
||||
history.replaceState({route: Routes.RETURNING_USER, step: 1}, '', path);
|
||||
break;
|
||||
default:
|
||||
history.replaceState(
|
||||
{route: Routes.LANDING, step: Routes.LANDING}, '', '/');
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies all elements when browser history is popped.
|
||||
window.addEventListener('popstate', notifyObservers);
|
||||
|
||||
// Notify the active element before unload.
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (currentRouteElement) {
|
||||
(currentRouteElement as {onRouteUnload: Function}).onRouteUnload();
|
||||
}
|
||||
});
|
||||
}
|
||||
main();
|
@ -1,57 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #import=../shared/animations.css.js
|
||||
* #include=animations
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.illustration {
|
||||
content: url(../images/set_default_light.svg);
|
||||
margin: auto;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.illustration {
|
||||
content: url(../images/set_default_dark.svg);
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--cr-primary-text-color);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 2.5rem;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: var(--cr-secondary-text-color);
|
||||
font-size: 1.25rem;
|
||||
font-weight: unset;
|
||||
line-height: 1.875rem;
|
||||
margin: auto;
|
||||
margin-top: 16px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.button-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
<if expr="is_win">
|
||||
cr-icon[icon='cr:open-in-new'] {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
</if>
|
@ -1,31 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {NuxSetAsDefaultElement} from './nux_set_as_default.js';
|
||||
|
||||
export function getHtml(this: NuxSetAsDefaultElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div class="container">
|
||||
<h1 tabindex="-1">${this.subtitle}</h1>
|
||||
<h2>$i18n{setDefaultSubHeader}</h2>
|
||||
<div class="illustration slide-in" aria-hidden="true"></div>
|
||||
<div class="button-bar">
|
||||
<cr-button id="declineButton" @click="${this.onDeclineClick_}">
|
||||
$i18n{skip}
|
||||
</cr-button>
|
||||
<step-indicator .model="${this.indicatorModel}"></step-indicator>
|
||||
<cr-button class="action-button" @click="${this.onSetDefaultClick_}">
|
||||
$i18n{setDefaultConfirm}
|
||||
<if expr="is_win">
|
||||
<cr-icon icon="cr:open-in-new" slot="suffix-icon"
|
||||
?hidden="${!this.isWin10_}">
|
||||
</cr-icon>
|
||||
</if>
|
||||
</cr-button>
|
||||
</div>
|
||||
</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
|
||||
// <if expr="is_win">
|
||||
import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
|
||||
import 'chrome://resources/cr_elements/icons.html.js';
|
||||
// </if>
|
||||
import '../shared/step_indicator.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {WebUiListenerMixinLit} from 'chrome://resources/cr_elements/web_ui_listener_mixin_lit.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {NavigationMixin} from '../navigation_mixin.js';
|
||||
import {navigateToNextStep} from '../router.js';
|
||||
import type {DefaultBrowserInfo, StepIndicatorModel} from '../shared/nux_types.js';
|
||||
|
||||
import {getCss} from './nux_set_as_default.css.js';
|
||||
import {getHtml} from './nux_set_as_default.html.js';
|
||||
import type {NuxSetAsDefaultProxy} from './nux_set_as_default_proxy.js';
|
||||
import {NuxSetAsDefaultProxyImpl} from './nux_set_as_default_proxy.js';
|
||||
|
||||
export interface NuxSetAsDefaultElement {
|
||||
$: {
|
||||
declineButton: HTMLElement,
|
||||
};
|
||||
}
|
||||
|
||||
const NuxSetAsDefaultElementBase =
|
||||
WebUiListenerMixinLit(NavigationMixin(CrLitElement));
|
||||
|
||||
export class NuxSetAsDefaultElement extends NuxSetAsDefaultElementBase {
|
||||
static get is() {
|
||||
return 'nux-set-as-default';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
indicatorModel: {type: Object},
|
||||
|
||||
// <if expr="is_win">
|
||||
isWin10_: {type: Boolean},
|
||||
// </if>
|
||||
};
|
||||
}
|
||||
|
||||
indicatorModel?: StepIndicatorModel;
|
||||
|
||||
// <if expr="is_win">
|
||||
protected isWin10_: boolean = loadTimeData.getBoolean('is_win10');
|
||||
// </if>
|
||||
|
||||
private browserProxy_: NuxSetAsDefaultProxy;
|
||||
private finalized_: boolean = false;
|
||||
navigateToNextStep: Function;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.subtitle = loadTimeData.getString('setDefaultHeader');
|
||||
this.navigateToNextStep = navigateToNextStep;
|
||||
this.browserProxy_ = NuxSetAsDefaultProxyImpl.getInstance();
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
this.addWebUiListener(
|
||||
'browser-default-state-changed',
|
||||
this.onDefaultBrowserChange_.bind(this));
|
||||
}
|
||||
|
||||
override onRouteEnter() {
|
||||
this.finalized_ = false;
|
||||
this.browserProxy_.recordPageShown();
|
||||
}
|
||||
|
||||
override onRouteExit() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.finalized_ = true;
|
||||
this.browserProxy_.recordNavigatedAwayThroughBrowserHistory();
|
||||
}
|
||||
|
||||
override onRouteUnload() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.finalized_ = true;
|
||||
this.browserProxy_.recordNavigatedAway();
|
||||
}
|
||||
|
||||
protected onDeclineClick_() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.browserProxy_.recordSkip();
|
||||
this.finished_();
|
||||
}
|
||||
|
||||
protected onSetDefaultClick_() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.browserProxy_.recordBeginSetDefault();
|
||||
this.browserProxy_.setAsDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically navigate to the next onboarding step once default changed.
|
||||
*/
|
||||
private onDefaultBrowserChange_(status: DefaultBrowserInfo) {
|
||||
if (status.isDefault) {
|
||||
this.browserProxy_.recordSuccessfullySetDefault();
|
||||
// Triggers toast in the containing welcome-app.
|
||||
this.dispatchEvent(new CustomEvent(
|
||||
'default-browser-change', {bubbles: true, composed: true}));
|
||||
this.finished_();
|
||||
return;
|
||||
}
|
||||
|
||||
// <if expr="is_macosx">
|
||||
// On Mac OS, we do not get a notification when the default browser changes.
|
||||
// This will fake the notification.
|
||||
window.setTimeout(() => {
|
||||
this.browserProxy_.requestDefaultBrowserState().then(
|
||||
this.onDefaultBrowserChange_.bind(this));
|
||||
}, 100);
|
||||
// </if>
|
||||
}
|
||||
|
||||
private finished_() {
|
||||
this.finalized_ = true;
|
||||
this.navigateToNextStep();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'nux-set-as-default': NuxSetAsDefaultElement;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(NuxSetAsDefaultElement.is, NuxSetAsDefaultElement);
|
@ -1,85 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {sendWithPromise} from 'chrome://resources/js/cr.js';
|
||||
|
||||
import type {DefaultBrowserInfo} from '../shared/nux_types.js';
|
||||
|
||||
const NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME =
|
||||
'FirstRun.NewUserExperience.SetAsDefaultInteraction';
|
||||
|
||||
enum NuxSetAsDefaultInteractions {
|
||||
PAGE_SHOWN = 0,
|
||||
NAVIGATED_AWAY,
|
||||
SKIP,
|
||||
CLICK_SET_DEFAULT,
|
||||
SUCCESSFULLY_SET_DEFAULT,
|
||||
NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY,
|
||||
}
|
||||
|
||||
const NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT =
|
||||
Object.keys(NuxSetAsDefaultInteractions).length;
|
||||
|
||||
export interface NuxSetAsDefaultProxy {
|
||||
requestDefaultBrowserState(): Promise<DefaultBrowserInfo>;
|
||||
setAsDefault(): void;
|
||||
recordPageShown(): void;
|
||||
recordNavigatedAway(): void;
|
||||
recordNavigatedAwayThroughBrowserHistory(): void;
|
||||
recordSkip(): void;
|
||||
recordBeginSetDefault(): void;
|
||||
recordSuccessfullySetDefault(): void;
|
||||
}
|
||||
|
||||
export class NuxSetAsDefaultProxyImpl implements NuxSetAsDefaultProxy {
|
||||
requestDefaultBrowserState() {
|
||||
return sendWithPromise('requestDefaultBrowserState');
|
||||
}
|
||||
|
||||
setAsDefault() {
|
||||
chrome.send('setAsDefaultBrowser');
|
||||
}
|
||||
|
||||
recordPageShown() {
|
||||
this.recordInteraction_(NuxSetAsDefaultInteractions.PAGE_SHOWN);
|
||||
}
|
||||
|
||||
recordNavigatedAway() {
|
||||
this.recordInteraction_(NuxSetAsDefaultInteractions.NAVIGATED_AWAY);
|
||||
}
|
||||
|
||||
recordNavigatedAwayThroughBrowserHistory() {
|
||||
this.recordInteraction_(
|
||||
NuxSetAsDefaultInteractions.NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY);
|
||||
}
|
||||
|
||||
recordSkip() {
|
||||
this.recordInteraction_(NuxSetAsDefaultInteractions.SKIP);
|
||||
}
|
||||
|
||||
recordBeginSetDefault() {
|
||||
this.recordInteraction_(NuxSetAsDefaultInteractions.CLICK_SET_DEFAULT);
|
||||
}
|
||||
|
||||
recordSuccessfullySetDefault() {
|
||||
this.recordInteraction_(
|
||||
NuxSetAsDefaultInteractions.SUCCESSFULLY_SET_DEFAULT);
|
||||
}
|
||||
|
||||
private recordInteraction_(interaction: number): void {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME, interaction,
|
||||
NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT);
|
||||
}
|
||||
|
||||
static getInstance(): NuxSetAsDefaultProxy {
|
||||
return instance || (instance = new NuxSetAsDefaultProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: NuxSetAsDefaultProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: NuxSetAsDefaultProxy|null = null;
|
@ -1,23 +0,0 @@
|
||||
/* Copyright 2022 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
button.action-link {
|
||||
-webkit-appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--cr-link-color);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-family: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
:host-context(html:not(.focus-outline-visible)) button.action-link {
|
||||
outline: none;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/* Copyright 2022 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
@keyframes fade-in {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes slide-in {
|
||||
0% { transform: translateX(var(--slide-in-length, 40px)); }
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation-delay: var(--animation-delay, 0);
|
||||
animation-duration: 200ms;
|
||||
animation-fill-mode: forwards;
|
||||
animation-name: fade-in;
|
||||
animation-timing-function: ease-in;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-in {
|
||||
animation-delay: var(--animation-delay, 0);
|
||||
animation-duration: 200ms;
|
||||
animation-fill-mode: forwards;
|
||||
animation-name: slide-in;
|
||||
animation-timing-function: ease;
|
||||
transform: translateX(30px);
|
||||
}
|
||||
|
||||
:host-context(html[dir='rtl']) .slide-in {
|
||||
--slide-in-length: -40px;
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {sendWithPromise} from 'chrome://resources/js/cr.js';
|
||||
|
||||
export interface BookmarkData {
|
||||
parentId: string;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type AddBookmarkCallback = (node: chrome.bookmarks.BookmarkTreeNode) =>
|
||||
void;
|
||||
|
||||
export interface BookmarkProxy {
|
||||
addBookmark(data: BookmarkData): Promise<chrome.bookmarks.BookmarkTreeNode>;
|
||||
|
||||
/** @param id ID provided by callback when bookmark was added. */
|
||||
removeBookmark(id: string): void;
|
||||
|
||||
toggleBookmarkBar(show: boolean): void;
|
||||
isBookmarkBarShown(): Promise<boolean>;
|
||||
}
|
||||
|
||||
export class BookmarkProxyImpl implements BookmarkProxy {
|
||||
addBookmark(data: BookmarkData) {
|
||||
return chrome.bookmarks.create(data);
|
||||
}
|
||||
|
||||
removeBookmark(id: string) {
|
||||
chrome.bookmarks.remove(id);
|
||||
}
|
||||
|
||||
toggleBookmarkBar(show: boolean) {
|
||||
chrome.send('toggleBookmarkBar', [show]);
|
||||
}
|
||||
|
||||
isBookmarkBarShown() {
|
||||
return sendWithPromise('isBookmarkBarShown');
|
||||
}
|
||||
|
||||
static getInstance(): BookmarkProxy {
|
||||
return bookmarkProxyInstance ||
|
||||
(bookmarkProxyInstance = new BookmarkProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: BookmarkProxy) {
|
||||
bookmarkProxyInstance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let bookmarkProxyInstance: BookmarkProxy|null = null;
|
||||
|
||||
// Wrapper for bookmark proxy to keep some additional states.
|
||||
export class BookmarkBarManager {
|
||||
private proxy_: BookmarkProxy;
|
||||
private isBarShown_: boolean = false;
|
||||
initialized: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this.proxy_ = BookmarkProxyImpl.getInstance();
|
||||
this.initialized = this.proxy_.isBookmarkBarShown().then((shown) => {
|
||||
this.isBarShown_ = shown;
|
||||
});
|
||||
}
|
||||
|
||||
getShown(): boolean {
|
||||
return this.isBarShown_;
|
||||
}
|
||||
|
||||
setShown(show: boolean) {
|
||||
this.isBarShown_ = show;
|
||||
this.proxy_.toggleBookmarkBar(show);
|
||||
}
|
||||
|
||||
static getInstance(): BookmarkBarManager {
|
||||
return managerInstance || (managerInstance = new BookmarkBarManager());
|
||||
}
|
||||
|
||||
static setInstance(obj: BookmarkBarManager) {
|
||||
managerInstance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let managerInstance: BookmarkBarManager|null = null;
|
@ -1,42 +0,0 @@
|
||||
/* Copyright 2022 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #import=./navi_colors.css.js
|
||||
* #include=navi-colors
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
.option {
|
||||
background: var(--cr-card-background-color);
|
||||
border: 1px solid var(--navi-border-color);
|
||||
color: var(--cr-primary-text-color);
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
box-shadow: var(--navi-option-box-shadow);
|
||||
}
|
||||
|
||||
.option-name {
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.button-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:host-context([dir=rtl]) iron-icon[icon='cr:chevron-right'] {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
iron-icon[icon='cr:chevron-right'] {
|
||||
height: 1.25rem;
|
||||
margin-inline-end: -.625rem;
|
||||
margin-inline-start: .375rem;
|
||||
width: 1.25rem;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<cr-iconset name="welcome" size="24">
|
||||
<svg>
|
||||
<defs>
|
||||
<g id="pause">
|
||||
<path d="M9 16h2V8H9Zm4 0h2V8h-2Zm-1 6q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3.35 2.325 5.675Q8.65 20 12 20Zm0-8Z">
|
||||
</g>
|
||||
<g id="play">
|
||||
<path d="m9.5 16.5 7-4.5-7-4.5ZM12 22q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3.35 2.325 5.675Q8.65 20 12 20Zm0-8Z">
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
||||
</cr-iconset>
|
@ -1,211 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* NuxNtpBackgroundInteractions enum.
|
||||
* These values are persisted to logs and should not be renumbered or
|
||||
* re-used.
|
||||
* See tools/metrics/histograms/enums.xml.
|
||||
*/
|
||||
export enum NuxNtpBackgroundInteractions {
|
||||
PAGE_SHOWN = 0,
|
||||
DID_NOTHING_AND_NAVIGATED_AWAY,
|
||||
DID_NOTHING_AND_CHOSE_SKIP,
|
||||
DID_NOTHING_AND_CHOSE_NEXT,
|
||||
CHOSE_AN_OPTION_AND_NAVIGATED_AWAY,
|
||||
CHOSE_AN_OPTION_AND_CHOSE_SKIP,
|
||||
CHOSE_AN_OPTION_AND_CHOSE_NEXT,
|
||||
NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY,
|
||||
BACKGROUND_IMAGE_FAILED_TO_LOAD,
|
||||
BACKGROUND_IMAGE_NEVER_LOADED,
|
||||
}
|
||||
|
||||
/**
|
||||
* NuxGoogleAppsInteractions enum.
|
||||
* These values are persisted to logs and should not be renumbered or
|
||||
* re-used.
|
||||
* See tools/metrics/histograms/enums.xml.
|
||||
*/
|
||||
export enum NuxGoogleAppsInteractions {
|
||||
PAGE_SHOWN = 0,
|
||||
NOT_USED_DEPRECATED,
|
||||
GET_STARTED_DEPRECATED,
|
||||
DID_NOTHING_AND_NAVIGATED_AWAY,
|
||||
DID_NOTHING_AND_CHOSE_SKIP,
|
||||
CHOSE_AN_OPTION_AND_NAVIGATED_AWAY,
|
||||
CHOSE_AN_OPTION_AND_CHOSE_SKIP,
|
||||
CHOSE_AN_OPTION_AND_CHOSE_NEXT,
|
||||
CLICKED_DISABLED_NEXT_BUTTON_AND_NAVIGATED_AWAY,
|
||||
CLICKED_DISABLED_NEXT_BUTTON_AND_CHOSE_SKIP,
|
||||
CLICKED_DISABLED_NEXT_BUTTON_AND_CHOSE_NEXT,
|
||||
DID_NOTHING_AND_CHOSE_NEXT,
|
||||
NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY,
|
||||
}
|
||||
|
||||
export interface ModuleMetricsProxy {
|
||||
recordPageShown(): void;
|
||||
recordDidNothingAndNavigatedAway(): void;
|
||||
recordDidNothingAndChoseSkip(): void;
|
||||
recordDidNothingAndChoseNext(): void;
|
||||
recordChoseAnOptionAndNavigatedAway(): void;
|
||||
recordChoseAnOptionAndChoseSkip(): void;
|
||||
recordChoseAnOptionAndChoseNext(): void;
|
||||
recordClickedDisabledNextButtonAndNavigatedAway(): void;
|
||||
recordClickedDisabledNextButtonAndChoseSkip(): void;
|
||||
recordClickedDisabledNextButtonAndChoseNext(): void;
|
||||
recordNavigatedAwayThroughBrowserHistory(): void;
|
||||
}
|
||||
|
||||
export class ModuleMetricsProxyImpl implements ModuleMetricsProxy {
|
||||
private interactionMetric_: string;
|
||||
private interactions_: any;
|
||||
|
||||
/**
|
||||
* @param histogramName The histogram that will record the module
|
||||
* navigation metrics.
|
||||
*/
|
||||
constructor(histogramName: string, interactions: any) {
|
||||
this.interactionMetric_ = histogramName;
|
||||
this.interactions_ = interactions;
|
||||
}
|
||||
|
||||
recordPageShown() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_, this.interactions_.PAGE_SHOWN,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordDidNothingAndNavigatedAway() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.DID_NOTHING_AND_NAVIGATED_AWAY,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordDidNothingAndChoseSkip() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_, this.interactions_.DID_NOTHING_AND_CHOSE_SKIP,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordDidNothingAndChoseNext() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_, this.interactions_.DID_NOTHING_AND_CHOSE_NEXT,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordChoseAnOptionAndNavigatedAway() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CHOSE_AN_OPTION_AND_NAVIGATED_AWAY,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordChoseAnOptionAndChoseSkip() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CHOSE_AN_OPTION_AND_CHOSE_SKIP,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordChoseAnOptionAndChoseNext() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CHOSE_AN_OPTION_AND_CHOSE_NEXT,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordClickedDisabledNextButtonAndNavigatedAway() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CLICKED_DISABLED_NEXT_BUTTON_AND_NAVIGATED_AWAY,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordClickedDisabledNextButtonAndChoseSkip() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CLICKED_DISABLED_NEXT_BUTTON_AND_CHOSE_SKIP,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordClickedDisabledNextButtonAndChoseNext() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.CLICKED_DISABLED_NEXT_BUTTON_AND_CHOSE_NEXT,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
|
||||
recordNavigatedAwayThroughBrowserHistory() {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
this.interactionMetric_,
|
||||
this.interactions_.NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY,
|
||||
Object.keys(this.interactions_).length);
|
||||
}
|
||||
}
|
||||
|
||||
export class ModuleMetricsManager {
|
||||
private metricsProxy_: ModuleMetricsProxy;
|
||||
private options_: any;
|
||||
firstPart: any;
|
||||
|
||||
constructor(metricsProxy: ModuleMetricsProxy) {
|
||||
this.metricsProxy_ = metricsProxy;
|
||||
this.options_ = {
|
||||
didNothing: {
|
||||
andNavigatedAway: metricsProxy.recordDidNothingAndNavigatedAway,
|
||||
andChoseSkip: metricsProxy.recordDidNothingAndChoseSkip,
|
||||
andChoseNext: metricsProxy.recordDidNothingAndChoseNext,
|
||||
},
|
||||
choseAnOption: {
|
||||
andNavigatedAway: metricsProxy.recordChoseAnOptionAndNavigatedAway,
|
||||
andChoseSkip: metricsProxy.recordChoseAnOptionAndChoseSkip,
|
||||
andChoseNext: metricsProxy.recordChoseAnOptionAndChoseNext,
|
||||
},
|
||||
clickedDisabledNextButton: {
|
||||
andNavigatedAway:
|
||||
metricsProxy.recordClickedDisabledNextButtonAndNavigatedAway,
|
||||
andChoseSkip: metricsProxy.recordClickedDisabledNextButtonAndChoseSkip,
|
||||
andChoseNext: metricsProxy.recordClickedDisabledNextButtonAndChoseNext,
|
||||
},
|
||||
};
|
||||
|
||||
this.firstPart = this.options_.didNothing;
|
||||
}
|
||||
|
||||
recordPageInitialized() {
|
||||
this.metricsProxy_.recordPageShown();
|
||||
this.firstPart = this.options_.didNothing;
|
||||
}
|
||||
|
||||
recordClickedOption() {
|
||||
// Only overwrite this.firstPart if it's not overwritten already
|
||||
if (this.firstPart === this.options_.didNothing) {
|
||||
this.firstPart = this.options_.choseAnOption;
|
||||
}
|
||||
}
|
||||
|
||||
recordClickedDisabledButton() {
|
||||
// Only overwrite this.firstPart if it's not overwritten already
|
||||
if (this.firstPart === this.options_.didNothing) {
|
||||
this.firstPart = this.options_.clickedDisabledNextButton;
|
||||
}
|
||||
}
|
||||
|
||||
recordNoThanks() {
|
||||
this.firstPart.andChoseSkip.call(this.metricsProxy_);
|
||||
}
|
||||
|
||||
recordGetStarted() {
|
||||
this.firstPart.andChoseNext.call(this.metricsProxy_);
|
||||
}
|
||||
|
||||
recordNavigatedAway() {
|
||||
this.firstPart.andNavigatedAway.call(this.metricsProxy_);
|
||||
}
|
||||
|
||||
recordBrowserBackOrForward() {
|
||||
this.metricsProxy_.recordNavigatedAwayThroughBrowserHistory();
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/* Copyright 2022 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
:host {
|
||||
--navi-border-color: var(--google-grey-300);
|
||||
--navi-check-icon-color: lightgrey;
|
||||
--navi-keyboard-focus-color: rgba(var(--google-blue-600-rgb), .4);
|
||||
--navi-option-box-shadow:
|
||||
0 1px 2px 0 rgba(var(--google-grey-800-rgb), .3),
|
||||
0 3px 6px 2px rgba(var(--google-grey-800-rgb), .15);
|
||||
--navi-option-icon-shadow-color: var(--google-grey-100);
|
||||
--navi-shape-blue-color: rgb(26, 115, 232); /* #1A73E8 */
|
||||
--navi-shape-green-color: rgb(49, 167, 83); /* #31A753 */
|
||||
--navi-shape-grey-color: rgb(241, 243, 244); /* #F1F3F4 */
|
||||
--navi-shape-red-color: rgb(233, 66, 53); /* #E94235 */
|
||||
--navi-shape-yellow-dots-color: rgb(253, 214, 99); /* #FDD663 */
|
||||
--navi-shape-yellow-semicircle-color: rgb(250, 207, 76); /* #FACF4C */
|
||||
--navi-step-indicator-active-color: var(--google-blue-600);
|
||||
--navi-step-indicator-color: var(--google-grey-200);
|
||||
--navi-wallpaper-text-color: var(--google-grey-700);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host {
|
||||
--navi-border-color: var(--google-grey-700);
|
||||
--navi-check-icon-color: var(--google-grey-700);
|
||||
--navi-keyboard-focus-color:
|
||||
rgba(var(--google-blue-300-rgb), .5);
|
||||
--navi-option-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .3),
|
||||
0 3px 6px 2px rgba(0, 0, 0, .15);
|
||||
--navi-option-icon-shadow-color: var(--google-grey-700);
|
||||
--navi-shape-blue-color: rgb(138, 180, 248); /* #8AB4F8 */
|
||||
--navi-shape-green-color: rgb(129, 201, 149); /* #81C995 */
|
||||
--navi-shape-grey-color: rgb(154, 160, 166); /* #9AA0A6 */
|
||||
--navi-shape-red-color: rgb(238, 103, 92); /* #EE675C */
|
||||
/* --navi-shape-yellow-dots-color is same color in dark mode */
|
||||
--navi-shape-yellow-semicircle-color: rgb(253, 214, 99); /* #FDD663 */
|
||||
--navi-step-indicator-active-color: var(--google-blue-300);
|
||||
--navi-step-indicator-color: var(--google-grey-500);
|
||||
--navi-wallpaper-text-color: var(--google-grey-200);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
export interface BookmarkListItem {
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface StepIndicatorModel {
|
||||
total: number;
|
||||
active: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(hcarmona): somehow reuse from
|
||||
* c/b/r/s/default_browser_page/default_browser_browser_proxy.js
|
||||
*/
|
||||
export interface DefaultBrowserInfo {
|
||||
canBeDefault: boolean;
|
||||
isDefault: boolean;
|
||||
isDisabledByPolicy: boolean;
|
||||
isUnknownError: boolean;
|
||||
}
|
@ -1,510 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=./icons.html.js
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
:host {
|
||||
--welcome-grey: rgb(218, 220, 224);
|
||||
--welcome-blue: rgb(57, 130, 248);
|
||||
--welcome-blue-tinted: rgb(138, 180, 248);
|
||||
--welcome-green: rgb(52, 168, 83);
|
||||
--welcome-green-tinted: rgb(129, 201, 149);
|
||||
--welcome-red: rgb(219, 68, 55);
|
||||
--welcome-yellow: rgb(251, 188, 4);
|
||||
--welcome-yellow-tinted: rgb(253, 214, 99);
|
||||
--welcome-animation-play-state: running;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
max-width: 1100px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host {
|
||||
--welcome-grey: rgb(95, 99, 104);
|
||||
--welcome-blue: rgb(57, 130, 248);
|
||||
--welcome-blue-tinted: rgb(26, 115, 232);
|
||||
--welcome-green: rgb(52, 168, 83);
|
||||
--welcome-green-tinted: rgb(30, 142, 62);
|
||||
--welcome-red: rgb(234, 66, 52);
|
||||
--welcome-yellow: rgb(251, 188, 4);
|
||||
--welcome-yellow-tinted: rgb(249, 171, 0);
|
||||
}
|
||||
}
|
||||
|
||||
:host([force-paused_]) {
|
||||
--welcome-animation-play-state: paused;
|
||||
}
|
||||
|
||||
#container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#canvas {
|
||||
min-height: 878px;
|
||||
min-width: 2728px;
|
||||
position: relative;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
#logo {
|
||||
background: url(../images/background_svgs/logo.svg);
|
||||
background-size: contain;
|
||||
border-radius: 50%;
|
||||
height: 250px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.line-container {
|
||||
border-radius: 8px;
|
||||
height: 6px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
transform-origin: center left;
|
||||
}
|
||||
|
||||
.line {
|
||||
border-radius: 8px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
transform-origin: center left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.line-fill {
|
||||
background-color: var(--line-color);
|
||||
border-radius: 8px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#blue-line {
|
||||
--line-color: var(--welcome-blue);
|
||||
left: 1225px;
|
||||
top: 278px;
|
||||
transform: rotate(225deg);
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
#green-line {
|
||||
--line-color: var(--welcome-green);
|
||||
left: 1170px;
|
||||
top: 517px;
|
||||
transform: rotate(-203deg);
|
||||
width: 68px;
|
||||
}
|
||||
|
||||
#red-line {
|
||||
--line-color: var(--welcome-red);
|
||||
left: 1574px;
|
||||
top: 339px;
|
||||
transform: rotate(-24deg);
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
#grey-line {
|
||||
--line-color: var(--welcome-grey);
|
||||
left: 1403px;
|
||||
top: 235px;
|
||||
transform: rotate(280deg);
|
||||
width: 68px;
|
||||
}
|
||||
|
||||
#yellow-line {
|
||||
--line-color: var(--welcome-yellow);
|
||||
left: 1308px;
|
||||
top: 655px;
|
||||
transform: rotate(104deg);
|
||||
width: 49px;
|
||||
}
|
||||
|
||||
.shape {
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
height: 400px;
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.dotted-line {
|
||||
-webkit-mask: url(../images/background_svgs/streamer_line.svg);
|
||||
-webkit-mask-position: 3px 0;
|
||||
-webkit-mask-size: 206px 12px;
|
||||
animation: dotted-line 1s infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
background-color: var(--welcome-grey);
|
||||
height: 12px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform-origin: center left;
|
||||
}
|
||||
|
||||
@keyframes dotted-line {
|
||||
to { -webkit-mask-position: 29px 0; }
|
||||
}
|
||||
|
||||
#dotted-line-1 {
|
||||
left: 1136px;
|
||||
top: 378px;
|
||||
transform: rotate(194deg);
|
||||
width: 126px;
|
||||
}
|
||||
|
||||
#dotted-line-2 {
|
||||
left: 1493px;
|
||||
top: 271px;
|
||||
transform: rotate(-50deg);
|
||||
width: 146px;
|
||||
}
|
||||
|
||||
#dotted-line-3 {
|
||||
left: 1545px;
|
||||
top: 525px;
|
||||
transform: rotate(25deg);
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#dotted-line-4 {
|
||||
left: 1219px;
|
||||
top: 626px;
|
||||
transform: rotate(128deg);
|
||||
width: 133px;
|
||||
}
|
||||
|
||||
.circle {
|
||||
background-color: var(--welcome-grey);
|
||||
border-radius: 50%;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.connectagon-container {
|
||||
--connectagon-shape-size: 64.77px;
|
||||
display: block;
|
||||
height: var(--connectagon-shape-size);
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.connectagon {
|
||||
height: 100%;
|
||||
transform-origin: 50% 50%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.connectagon .circle {
|
||||
background-color: var(--connectagon-shape-color);
|
||||
border-radius: 50%;
|
||||
float: left;
|
||||
height: var(--connectagon-shape-size);
|
||||
position: relative;
|
||||
width: var(--connectagon-shape-size);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.connectagon .square {
|
||||
background-color: var(--connectagon-connector-color);
|
||||
float: left;
|
||||
height: var(--connectagon-shape-size);
|
||||
margin-inline-start: calc(var(--connectagon-shape-size)/-2);
|
||||
position: relative;
|
||||
width: 59px;
|
||||
}
|
||||
|
||||
.connectagon .hexagon {
|
||||
-webkit-mask: url(../images/background_svgs/hexagon.svg) no-repeat top left;
|
||||
background-color: var(--connectagon-shape-color);
|
||||
float: left;
|
||||
height: var(--connectagon-shape-size);
|
||||
position: relative;
|
||||
width: 72.78px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:host-context([dir='rtl']) .connectagon :is(.circle, .square, .hexagon) {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.connectagon .circle+.square+.hexagon,
|
||||
.connectagon .circle+.square+.circle {
|
||||
margin-inline-start: -27.39px;
|
||||
}
|
||||
|
||||
.connectagon .hexagon+.square+.hexagon {
|
||||
margin-inline-start: -26.39px;
|
||||
}
|
||||
|
||||
#yellow-connectagon {
|
||||
--connectagon-shape-color: var(--welcome-yellow);
|
||||
--connectagon-connector-color: var(--welcome-yellow-tinted);
|
||||
animation: yellow-connectagon-translate 4s alternate infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
left: 549px;
|
||||
top: 156px;
|
||||
transform: translate(-50%, -50%) rotate(51deg);
|
||||
}
|
||||
|
||||
@keyframes yellow-connectagon-translate {
|
||||
to {
|
||||
transform: translate(calc(-50% - 36px), calc(-50% - 62px)) rotate(51deg);
|
||||
}
|
||||
}
|
||||
|
||||
#yellow-connectagon .connectagon {
|
||||
animation: yellow-connectagon-rotate 4s infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
@keyframes yellow-connectagon-rotate {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#green-triangle {
|
||||
-webkit-mask: url(../images/background_svgs/triangle.svg);
|
||||
animation: green-triangle 3s infinite cubic-bezier(.63,.03,.41,.98);
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
background-color: var(--welcome-green);
|
||||
left: 1813px;
|
||||
top: 0;
|
||||
transform: translate(-50%, -50%) rotate(-10deg);
|
||||
transform-origin: 200px 300px;
|
||||
}
|
||||
|
||||
@keyframes green-triangle {
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(350deg);
|
||||
}
|
||||
}
|
||||
|
||||
#blue-connectagon {
|
||||
--connectagon-shape-color: var(--welcome-blue);
|
||||
--connectagon-connector-color: var(--welcome-blue-tinted);
|
||||
animation: blue-connectagon 4s alternate infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
left: 2157px;
|
||||
top: 249px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@keyframes blue-connectagon {
|
||||
50% {
|
||||
transform: translate(calc(-50% + 10px), calc(-50% + 30px));
|
||||
}
|
||||
100% {
|
||||
transform: translate(calc(-50%), calc(-50% + 60px));
|
||||
}
|
||||
}
|
||||
|
||||
#green-connectagon {
|
||||
--connectagon-shape-color: var(--welcome-green);
|
||||
--connectagon-connector-color: var(--welcome-green-tinted);
|
||||
animation: green-connectagon-translate 6s alternate infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
left: 851px;
|
||||
top: 766px;
|
||||
transform: translate(-50%, -50%) rotate(139deg);
|
||||
}
|
||||
|
||||
@keyframes green-connectagon-translate {
|
||||
100% {
|
||||
transform: translate(calc(-50% + 80px), calc(-50% + 20px)) rotate(139deg);
|
||||
}
|
||||
}
|
||||
|
||||
#green-connectagon .connectagon {
|
||||
animation: green-connectagon-rotate 12s infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
@keyframes green-connectagon-rotate {
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#square {
|
||||
-webkit-mask: url(../images/background_svgs/square.svg);
|
||||
animation: square 4s infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
background-color: var(--welcome-yellow);
|
||||
left: 1822px;
|
||||
top: 716px;
|
||||
transform: translate(-50%, -50%) rotate(29deg);
|
||||
}
|
||||
|
||||
@keyframes square {
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(389deg);
|
||||
}
|
||||
}
|
||||
|
||||
#grey-triangle {
|
||||
-webkit-mask: url(../images/background_svgs/triangle.svg);
|
||||
background-color: var(--welcome-grey);
|
||||
left: 726px;
|
||||
top: 414px;
|
||||
transform: translate(-50%, -50%) rotate(-16deg);
|
||||
}
|
||||
|
||||
#grey-circle-1 {
|
||||
left: 380px;
|
||||
top: 600px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#grey-circle-2 {
|
||||
left: 1526px;
|
||||
top: 739px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#grey-lozenge {
|
||||
-webkit-mask: url(../images/background_svgs/lozenge.svg) no-repeat top left;
|
||||
background-color: var(--welcome-grey);
|
||||
left: 2351px;
|
||||
top: 491px;
|
||||
transform: translate(-50%, -50%) rotate(-32deg);
|
||||
}
|
||||
|
||||
#password-field {
|
||||
-webkit-mask: url(../images/background_svgs/password_field.svg);
|
||||
background-color: var(--welcome-grey);
|
||||
left: 860px;
|
||||
top: 210px;
|
||||
transform: translate(-50%, -50%) rotate(-11deg);
|
||||
}
|
||||
|
||||
#password-field-input {
|
||||
-webkit-mask: url(../images/background_svgs/password.svg);
|
||||
-webkit-mask-position: top left;
|
||||
-webkit-mask-size: 400px 400px;
|
||||
animation: password-field-input 2s steps(1) infinite;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
background-color: var(--welcome-green);
|
||||
left: 604px;
|
||||
top: 78px;
|
||||
transform: rotate(-11deg);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
@keyframes password-field-input {
|
||||
0% { width: 150px; }
|
||||
15% { width: 182px; }
|
||||
30% { width: 218px; }
|
||||
45% { width: 249px; }
|
||||
60% { width: 400px; }
|
||||
100% { width: 400px; }
|
||||
}
|
||||
|
||||
#bookmarks-background {
|
||||
-webkit-mask: url(../images/background_svgs/bookmarks_background.svg)
|
||||
no-repeat top left;
|
||||
background-color: var(--welcome-grey);
|
||||
left: 937px;
|
||||
top: 570px;
|
||||
transform: translate(-50%, -50%) rotate(10deg);
|
||||
}
|
||||
|
||||
#bookmarks-foreground {
|
||||
-webkit-mask: url(../images/background_svgs/bookmarks_foreground.svg)
|
||||
no-repeat top left;
|
||||
background-color: var(--welcome-blue);
|
||||
left: 937px;
|
||||
top: 568px;
|
||||
transform: translate(-50%, -50%) rotate(10deg);
|
||||
}
|
||||
|
||||
#devices {
|
||||
-webkit-mask: url(../images/background_svgs/devices.svg);
|
||||
background-color: var(--welcome-grey);
|
||||
left: 1885px;
|
||||
top: 446px;
|
||||
transform: translate(-50%, -50%) rotate(-9deg);
|
||||
}
|
||||
|
||||
#devices-check {
|
||||
-webkit-mask: url(../images/background_svgs/devices_check.svg);
|
||||
background-color: var(--welcome-blue);
|
||||
left: 1885px;
|
||||
top: 446px;
|
||||
transform: translate(-50%, -50%) rotate(-9deg);
|
||||
}
|
||||
|
||||
#devices-circle {
|
||||
/* Clip the top-left and bottom-right quadrants. */
|
||||
clip-path: polygon(
|
||||
48% 0, 100% 0, 100% 50%, 50% 50%, 52% 100%, 0 100%, 0 50%, 50% 47%);
|
||||
left: 1832px;
|
||||
top: 456px;
|
||||
transform: translate(-50%, -50%) rotate(-9deg);
|
||||
}
|
||||
|
||||
#devices-circle-image {
|
||||
-webkit-mask: url(../images/background_svgs/streamer_circle.svg);
|
||||
animation: devices-circle 11s infinite linear;
|
||||
animation-play-state: var(--welcome-animation-play-state);
|
||||
background-color: var(--welcome-green);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@keyframes devices-circle {
|
||||
to { transform: rotate(-360deg); }
|
||||
}
|
||||
|
||||
#playPause {
|
||||
--cr-icon-button-fill-color: var(--cr-secondary-text-color);
|
||||
--cr-icon-button-icon-size: 24px;
|
||||
bottom: 100px;
|
||||
left: 90%;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
transition: opacity 300ms linear 500ms;
|
||||
}
|
||||
|
||||
:host-context([dir=rtl]) #playPause {
|
||||
left: auto;
|
||||
right: 90%;
|
||||
}
|
||||
|
||||
:host(:hover) #playPause,
|
||||
#playPause:focus-visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
:host {
|
||||
--welcome-animation-play-state: paused;
|
||||
}
|
||||
|
||||
#playPause {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {OnboardingBackgroundElement} from './onboarding_background.js';
|
||||
|
||||
export function getHtml(this: OnboardingBackgroundElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div id="container">
|
||||
<div id="canvas">
|
||||
<div class="shape" id="logo" @click="${this.onLogoClick_}"></div>
|
||||
|
||||
<!-- Lines surrounding logo. -->
|
||||
<div class="line-container" id="blue-line">
|
||||
<div class="line"><div class="line-fill"></div></div>
|
||||
</div>
|
||||
<div class="line-container" id="green-line">
|
||||
<div class="line"><div class="line-fill"></div></div>
|
||||
</div>
|
||||
<div class="line-container" id="red-line">
|
||||
<div class="line"><div class="line-fill"></div></div>
|
||||
</div>
|
||||
<div class="line-container" id="grey-line">
|
||||
<div class="line"><div class="line-fill"></div></div>
|
||||
</div>
|
||||
<div class="line-container" id="yellow-line">
|
||||
<div class="line"><div class="line-fill"></div></div>
|
||||
</div>
|
||||
|
||||
<!-- Grey dotted lines surrounding logo. -->
|
||||
<div class="shape dotted-line" id="dotted-line-1"></div>
|
||||
<div class="shape dotted-line" id="dotted-line-2"></div>
|
||||
<div class="shape dotted-line" id="dotted-line-3"></div>
|
||||
<div class="shape dotted-line" id="dotted-line-4"></div>
|
||||
|
||||
<!-- Connectagons. -->
|
||||
<div class="connectagon-container" id="yellow-connectagon">
|
||||
<div class="connectagon">
|
||||
<div class="circle"></div>
|
||||
<div class="square"></div>
|
||||
<div class="hexagon"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="connectagon-container" id="blue-connectagon">
|
||||
<div class="connectagon">
|
||||
<div class="hexagon"></div>
|
||||
<div class="square"></div>
|
||||
<div class="hexagon"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="connectagon-container" id="green-connectagon">
|
||||
<div class="connectagon">
|
||||
<div class="circle"></div>
|
||||
<div class="square"></div>
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Colored shapes. -->
|
||||
<div class="shape" id="green-triangle"></div>
|
||||
<div class="shape" id="square"></div>
|
||||
|
||||
<!-- Grey shapes. -->
|
||||
<div class="shape" id="grey-triangle"></div>
|
||||
<div class="shape circle" id="grey-circle-1"></div>
|
||||
<div class="shape circle" id="grey-circle-2"></div>
|
||||
<div class="shape" id="grey-lozenge"></div>
|
||||
|
||||
<!-- Password field image. -->
|
||||
<div class="shape" id="password-field"></div>
|
||||
<div class="shape" id="password-field-input"></div>
|
||||
|
||||
<!-- Bookmarks image. -->
|
||||
<div class="shape" id="bookmarks-background"></div>
|
||||
<div class="shape" id="bookmarks-foreground"></div>
|
||||
|
||||
<!-- Connected devices image. -->
|
||||
<div class="shape" id="devices"></div>
|
||||
<div class="shape" id="devices-check"></div>
|
||||
<div class="shape" id="devices-circle">
|
||||
<div id="devices-circle-image"></div>
|
||||
</div>
|
||||
|
||||
<!-- Temp: Overlay of graphic -->
|
||||
<div id="overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<cr-icon-button id="playPause" iron-icon="${this.getPlayPauseIcon_()}"
|
||||
@click="${this.onPlayPauseClick_}"
|
||||
aria-label="${this.getPlayPauseLabel_()}">
|
||||
</cr-icon-button>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* @fileoverview This element contains a set of SVGs that together acts as an
|
||||
* animated and responsive background for any page that contains it.
|
||||
*/
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {assert} from 'chrome://resources/js/assert.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {getCss} from './onboarding_background.css.js';
|
||||
import {getHtml} from './onboarding_background.html.js';
|
||||
|
||||
export interface OnboardingBackgroundElement {
|
||||
$: {
|
||||
logo: HTMLElement,
|
||||
};
|
||||
}
|
||||
|
||||
export class OnboardingBackgroundElement extends CrLitElement {
|
||||
static get is() {
|
||||
return 'onboarding-background';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
forcePaused_: {
|
||||
type: Boolean,
|
||||
reflect: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private animations_: Animation[] = [];
|
||||
private forcePaused_: boolean =
|
||||
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
const details: Array<[string, number]> = [
|
||||
['blue-line', 60],
|
||||
['green-line', 68],
|
||||
['red-line', 45],
|
||||
['grey-line', 68],
|
||||
['yellow-line', 49],
|
||||
];
|
||||
details.forEach(([id, width]) => {
|
||||
const element = this.shadowRoot!.querySelector<HTMLElement>(`#${id}`);
|
||||
assert(element);
|
||||
this.createLineAnimation_(element, width);
|
||||
});
|
||||
}
|
||||
|
||||
private createLineAnimation_(lineContainer: HTMLElement, width: number) {
|
||||
const line = lineContainer.firstElementChild as HTMLElement;
|
||||
const lineFill = line.firstElementChild as HTMLElement;
|
||||
const pointOptions = {
|
||||
endDelay: 3250,
|
||||
fill: 'forwards' as FillMode,
|
||||
duration: 750,
|
||||
};
|
||||
|
||||
const startPointAnimation = lineFill.animate(
|
||||
[
|
||||
{width: '0px'},
|
||||
{width: `${width}px`},
|
||||
],
|
||||
Object.assign({}, pointOptions, {easing: 'cubic-bezier(.6,0,0,1)'}));
|
||||
startPointAnimation.pause();
|
||||
this.animations_.push(startPointAnimation);
|
||||
this.loopAnimation_(startPointAnimation);
|
||||
|
||||
const endPointWidthAnimation = line.animate(
|
||||
[
|
||||
{width: `${width}px`},
|
||||
{width: '0px'},
|
||||
],
|
||||
Object.assign(
|
||||
{}, pointOptions, {easing: 'cubic-bezier(.66,0,.86,.25)'}));
|
||||
endPointWidthAnimation.pause();
|
||||
this.animations_.push(endPointWidthAnimation);
|
||||
this.loopAnimation_(endPointWidthAnimation);
|
||||
|
||||
const endPointTransformAnimation = line.animate(
|
||||
[
|
||||
{transform: `translateX(0)`},
|
||||
{transform: `translateX(${width}px)`},
|
||||
],
|
||||
Object.assign({}, pointOptions, {
|
||||
easing: 'cubic-bezier(.66,0,.86,.25)',
|
||||
}));
|
||||
endPointTransformAnimation.pause();
|
||||
this.animations_.push(endPointTransformAnimation);
|
||||
this.loopAnimation_(endPointTransformAnimation);
|
||||
|
||||
const lineTransformAnimation = lineContainer.animate(
|
||||
[
|
||||
{transform: `translateX(0)`},
|
||||
{transform: `translateX(40px)`},
|
||||
],
|
||||
{
|
||||
composite: 'add', // There is already a rotate on the line.
|
||||
duration: 1500,
|
||||
easing: 'cubic-bezier(0,.56,.46,1)',
|
||||
endDelay: 2500,
|
||||
fill: 'forwards',
|
||||
});
|
||||
lineTransformAnimation.pause();
|
||||
this.animations_.push(lineTransformAnimation);
|
||||
this.loopAnimation_(lineTransformAnimation);
|
||||
}
|
||||
|
||||
protected getPlayPauseIcon_(): string {
|
||||
return this.forcePaused_ ? 'welcome:play' : 'welcome:pause';
|
||||
}
|
||||
|
||||
protected getPlayPauseLabel_(): string {
|
||||
return loadTimeData.getString(
|
||||
this.forcePaused_ ? 'landingPlayAnimations' : 'landingPauseAnimations');
|
||||
}
|
||||
|
||||
private loopAnimation_(animation: Animation) {
|
||||
// Animations that have a delay after them can only be looped by re-playing
|
||||
// them as soon as they finish. The |endDelay| property of JS animations
|
||||
// only works if |iterations| is 1, and the |delay| property runs before
|
||||
// the animation even plays.
|
||||
animation.onfinish = () => {
|
||||
animation.play();
|
||||
};
|
||||
}
|
||||
|
||||
protected onLogoClick_() {
|
||||
this.$.logo.animate(
|
||||
{
|
||||
transform: [
|
||||
'translate(-50%, -50%)',
|
||||
'translate(-50%, -50%) rotate(-10turn)',
|
||||
],
|
||||
},
|
||||
{
|
||||
duration: 500,
|
||||
easing: 'cubic-bezier(1, 0, 0, 1)',
|
||||
});
|
||||
}
|
||||
|
||||
protected onPlayPauseClick_() {
|
||||
if (this.forcePaused_) {
|
||||
this.play();
|
||||
} else {
|
||||
this.pause();
|
||||
}
|
||||
|
||||
this.forcePaused_ = !this.forcePaused_;
|
||||
}
|
||||
|
||||
pause() {
|
||||
this.animations_.forEach(animation => animation.pause());
|
||||
}
|
||||
|
||||
play() {
|
||||
if (this.forcePaused_) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.animations_.forEach(animation => animation.play());
|
||||
}
|
||||
}
|
||||
customElements.define(
|
||||
OnboardingBackgroundElement.is, OnboardingBackgroundElement);
|
@ -1,73 +0,0 @@
|
||||
/* Copyright 2022 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_shared_vars.css.js
|
||||
* #import=./navi_colors.css.js
|
||||
* #include=navi-colors
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
#container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: fit-content;
|
||||
justify-content: center;
|
||||
margin: auto;
|
||||
min-height: 100%;
|
||||
min-width: 800px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#text {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-basis: 45vh;
|
||||
flex-direction: column;
|
||||
/* Put the text above the onboarding-background. */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--cr-primary-text-color);
|
||||
font-size: 4rem;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 16px;
|
||||
order: 2;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subheading {
|
||||
color: var(--cr-secondary-text-color);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 2.25rem;
|
||||
margin: 0;
|
||||
opacity: 0.8;
|
||||
order: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
cr-button {
|
||||
font-size: 1rem;
|
||||
height: 3rem;
|
||||
padding-bottom: 12px;
|
||||
padding-top: 12px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
width: 256px;
|
||||
}
|
||||
|
||||
.action-link {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
margin-top: 24px;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=./navi_colors.css.js
|
||||
* #include=navi-colors
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
:host {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
span {
|
||||
background: var(--navi-step-indicator-color);
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: 8px;
|
||||
margin: 0 4px;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
span.active {
|
||||
background: var(--navi-step-indicator-active-color);
|
||||
}
|
||||
|
||||
.screen-reader-only {
|
||||
clip: rect(0, 0, 0, 0);
|
||||
position: fixed;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html, nothing} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {StepIndicatorElement} from './step_indicator.js';
|
||||
|
||||
export function getHtml(this: StepIndicatorElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
${this.dots_.map((_item, index) => html`
|
||||
<span class="${this.getActiveClass_(index) || nothing}"></span>
|
||||
`)}
|
||||
<div class="screen-reader-only">${this.getLabel_()}</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* @fileoverview This element contains a set of SVGs that together acts as an
|
||||
* animated and responsive background for any page that contains it.
|
||||
*/
|
||||
|
||||
import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js';
|
||||
import {assert} from 'chrome://resources/js/assert.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
import type {PropertyValues} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {StepIndicatorModel} from './nux_types.js';
|
||||
import {getCss} from './step_indicator.css.js';
|
||||
import {getHtml} from './step_indicator.html.js';
|
||||
|
||||
const StepIndicatorElementBase = I18nMixinLit(CrLitElement);
|
||||
|
||||
export class StepIndicatorElement extends StepIndicatorElementBase {
|
||||
static get is() {
|
||||
return 'step-indicator';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
model: {type: Object},
|
||||
dots_: {type: Array},
|
||||
};
|
||||
}
|
||||
|
||||
model?: StepIndicatorModel;
|
||||
protected dots_: number[] = [];
|
||||
|
||||
override willUpdate(changedProperties: PropertyValues<this>) {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
if (changedProperties.has('model')) {
|
||||
this.dots_ = this.computeDots_();
|
||||
}
|
||||
}
|
||||
|
||||
protected getLabel_(): string {
|
||||
return this.model ?
|
||||
this.i18n('stepsLabel', this.model!.active + 1, this.model!.total) :
|
||||
'';
|
||||
}
|
||||
|
||||
private computeDots_(): number[] {
|
||||
assert(this.model);
|
||||
// If total is 1, show nothing.
|
||||
const array: number[] = new Array(this.model.total > 1 ? this.model.total : 0);
|
||||
array.fill(0);
|
||||
return array;
|
||||
}
|
||||
|
||||
protected getActiveClass_(index: number): string {
|
||||
assert(this.model);
|
||||
return index === this.model.active ? 'active' : '';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(StepIndicatorElement.is, StepIndicatorElement);
|
@ -1,21 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=./shared/animations.css.js
|
||||
* #import=./shared/splash_pages_shared.css.js
|
||||
* #import=./shared/action_link_style.css.js
|
||||
* #include=animations action-link-style splash-pages-shared
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
onboarding-background {
|
||||
--animation-delay: 150ms;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
outline: none;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {SigninViewElement} from './signin_view.js';
|
||||
|
||||
export function getHtml(this: SigninViewElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<div id="container">
|
||||
<onboarding-background id="background" class="fade-in">
|
||||
</onboarding-background>
|
||||
<div id="text">
|
||||
<div class="header">
|
||||
<h1 tabindex="-1">$i18n{signInHeader}</h1>
|
||||
<div class="subheading">$i18n{signInSubHeader}</div>
|
||||
</div>
|
||||
<cr-button class="action-button" @click="${this.onSignInClick_}">
|
||||
$i18n{signIn}
|
||||
</cr-button>
|
||||
<button class="action-link" @click="${this.onNoThanksClick_}">
|
||||
$i18n{noThanks}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
|
||||
import './shared/onboarding_background.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import {NavigationMixin} from './navigation_mixin.js';
|
||||
import type {OnboardingBackgroundElement} from './shared/onboarding_background.js';
|
||||
import {getCss} from './signin_view.css.js';
|
||||
import {getHtml} from './signin_view.html.js';
|
||||
import type {SigninViewProxy} from './signin_view_proxy.js';
|
||||
import {SigninViewProxyImpl} from './signin_view_proxy.js';
|
||||
import type {WelcomeBrowserProxy} from './welcome_browser_proxy.js';
|
||||
import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
|
||||
|
||||
export interface SigninViewElement {
|
||||
$: {
|
||||
background: OnboardingBackgroundElement,
|
||||
};
|
||||
}
|
||||
|
||||
const SigninViewElementBase = NavigationMixin(CrLitElement);
|
||||
|
||||
export class SigninViewElement extends SigninViewElementBase {
|
||||
static get is() {
|
||||
return 'signin-view';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
private finalized_: boolean = false;
|
||||
private welcomeBrowserProxy_: WelcomeBrowserProxy;
|
||||
private signinViewProxy_: SigninViewProxy;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.signinViewProxy_ = SigninViewProxyImpl.getInstance();
|
||||
this.welcomeBrowserProxy_ = WelcomeBrowserProxyImpl.getInstance();
|
||||
}
|
||||
|
||||
override onRouteEnter() {
|
||||
this.finalized_ = false;
|
||||
this.signinViewProxy_.recordPageShown();
|
||||
this.$.background.play();
|
||||
}
|
||||
|
||||
override onRouteExit() {
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.finalized_ = true;
|
||||
this.signinViewProxy_.recordNavigatedAwayThroughBrowserHistory();
|
||||
this.$.background.pause();
|
||||
}
|
||||
|
||||
override onRouteUnload() {
|
||||
// URL is expected to change when signing in or skipping.
|
||||
if (this.finalized_) {
|
||||
return;
|
||||
}
|
||||
this.finalized_ = true;
|
||||
this.signinViewProxy_.recordNavigatedAway();
|
||||
}
|
||||
|
||||
protected onSignInClick_() {
|
||||
this.finalized_ = true;
|
||||
this.signinViewProxy_.recordSignIn();
|
||||
this.welcomeBrowserProxy_.handleActivateSignIn(null);
|
||||
}
|
||||
|
||||
protected onNoThanksClick_() {
|
||||
this.finalized_ = true;
|
||||
this.signinViewProxy_.recordSkip();
|
||||
this.welcomeBrowserProxy_.handleUserDecline();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'signin-view': SigninViewElement;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(SigninViewElement.is, SigninViewElement);
|
@ -1,64 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
const NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME =
|
||||
'FirstRun.NewUserExperience.SignInInterstitialInteraction';
|
||||
|
||||
enum NuxSignInInterstitialInteractions {
|
||||
PAGE_SHOWN = 0,
|
||||
NAVIGATED_AWAY,
|
||||
SKIP,
|
||||
SIGN_IN,
|
||||
NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY,
|
||||
}
|
||||
|
||||
const NUX_SIGNIN_VIEW_INTERACTIONS_COUNT =
|
||||
Object.keys(NuxSignInInterstitialInteractions).length;
|
||||
|
||||
export interface SigninViewProxy {
|
||||
recordPageShown(): void;
|
||||
recordNavigatedAway(): void;
|
||||
recordNavigatedAwayThroughBrowserHistory(): void;
|
||||
recordSkip(): void;
|
||||
recordSignIn(): void;
|
||||
}
|
||||
|
||||
export class SigninViewProxyImpl implements SigninViewProxy {
|
||||
recordPageShown() {
|
||||
this.recordInteraction_(NuxSignInInterstitialInteractions.PAGE_SHOWN);
|
||||
}
|
||||
|
||||
recordNavigatedAway() {
|
||||
this.recordInteraction_(NuxSignInInterstitialInteractions.NAVIGATED_AWAY);
|
||||
}
|
||||
|
||||
recordNavigatedAwayThroughBrowserHistory() {
|
||||
this.recordInteraction_(NuxSignInInterstitialInteractions
|
||||
.NAVIGATED_AWAY_THROUGH_BROWSER_HISTORY);
|
||||
}
|
||||
|
||||
recordSkip() {
|
||||
this.recordInteraction_(NuxSignInInterstitialInteractions.SKIP);
|
||||
}
|
||||
|
||||
recordSignIn() {
|
||||
this.recordInteraction_(NuxSignInInterstitialInteractions.SIGN_IN);
|
||||
}
|
||||
|
||||
private recordInteraction_(interaction: number): void {
|
||||
chrome.metricsPrivate.recordEnumerationValue(
|
||||
NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME, interaction,
|
||||
NUX_SIGNIN_VIEW_INTERACTIONS_COUNT);
|
||||
}
|
||||
|
||||
static getInstance(): SigninViewProxy {
|
||||
return instance || (instance = new SigninViewProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: SigninViewProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: SigninViewProxy|null = null;
|
@ -1,7 +0,0 @@
|
||||
/* Copyright 2018 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<!doctype html>
|
||||
<html dir="$i18n{textdirection}" lang="$i18n{language}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<title>$i18n{headerText}</title>
|
||||
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
|
||||
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
|
||||
<link rel="stylesheet" href="welcome.css">
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
background: var(--md-background-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script type="module" src="welcome_app.js"></script>
|
||||
<welcome-app></welcome-app>
|
||||
</body>
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
/* Copyright 2024 The Chromium Authors
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #import=chrome://resources/cr_elements/cr_hidden_style_lit.css.js
|
||||
* #include=cr-hidden-style-lit
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
#viewManager {
|
||||
display: flex;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#viewManager :-webkit-any(nux-google-apps, nux-ntp-background,
|
||||
nux-set-as-default) {
|
||||
/* Override cr-view-manager's default styling for view. */
|
||||
bottom: initial;
|
||||
left: initial;
|
||||
margin: auto;
|
||||
position: unset;
|
||||
right: initial;
|
||||
top: initial;
|
||||
}
|
||||
|
||||
cr-toast {
|
||||
min-width: initial;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {WelcomeAppElement} from './welcome_app.js';
|
||||
|
||||
export function getHtml(this: WelcomeAppElement) {
|
||||
return html`<!--_html_template_start_-->
|
||||
<cr-view-manager id="viewManager" ?hidden="${!this.modulesInitialized_}">
|
||||
<landing-view id="step-landing" slot="view" class="active"></landing-view>
|
||||
</cr-view-manager>
|
||||
<cr-toast duration="3000">
|
||||
<div>$i18n{defaultBrowserChanged}</div>
|
||||
</cr-toast>
|
||||
<!--_html_template_end_-->`;
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
|
||||
import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
|
||||
import './google_apps/nux_google_apps.js';
|
||||
import './landing_view.js';
|
||||
import './ntp_background/nux_ntp_background.js';
|
||||
import './set_as_default/nux_set_as_default.js';
|
||||
import './signin_view.js';
|
||||
import '/strings.m.js';
|
||||
|
||||
import type {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
|
||||
import {assert} from 'chrome://resources/js/assert.js';
|
||||
import {FocusOutlineManager} from 'chrome://resources/js/focus_outline_manager.js';
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {NuxGoogleAppsElement} from './google_apps/nux_google_apps.js';
|
||||
import {NavigationMixin} from './navigation_mixin.js';
|
||||
import type {NuxNtpBackgroundElement} from './ntp_background/nux_ntp_background.js';
|
||||
import {Routes} from './router.js';
|
||||
import type {NuxSetAsDefaultElement} from './set_as_default/nux_set_as_default.js';
|
||||
import {NuxSetAsDefaultProxyImpl} from './set_as_default/nux_set_as_default_proxy.js';
|
||||
import {BookmarkBarManager} from './shared/bookmark_proxy.js';
|
||||
import {getCss} from './welcome_app.css.js';
|
||||
import {getHtml} from './welcome_app.html.js';
|
||||
import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
|
||||
|
||||
/**
|
||||
* The strings contained in the arrays should be valid DOM-element tag names.
|
||||
*/
|
||||
interface NuxOnboardingModules {
|
||||
'new-user': string[];
|
||||
'returning-user': string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* This list needs to be updated if new modules need to be supported in the
|
||||
* onboarding flow.
|
||||
*/
|
||||
const MODULES_WHITELIST: Set<string> = new Set([
|
||||
'nux-google-apps',
|
||||
'nux-ntp-background',
|
||||
'nux-set-as-default',
|
||||
'signin-view',
|
||||
]);
|
||||
|
||||
/**
|
||||
* This list needs to be updated if new modules that need step-indicators are
|
||||
* added.
|
||||
*/
|
||||
const MODULES_NEEDING_INDICATOR: Set<string> =
|
||||
new Set(['nux-google-apps', 'nux-ntp-background', 'nux-set-as-default']);
|
||||
|
||||
export interface WelcomeAppElement {
|
||||
$: {
|
||||
viewManager: CrViewManagerElement,
|
||||
};
|
||||
}
|
||||
|
||||
const WelcomeAppElementBase = NavigationMixin(CrLitElement);
|
||||
|
||||
/** @polymer */
|
||||
export class WelcomeAppElement extends WelcomeAppElementBase {
|
||||
static get is() {
|
||||
return 'welcome-app';
|
||||
}
|
||||
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
modulesInitialized_: {type: Boolean},
|
||||
};
|
||||
}
|
||||
private currentRoute_: Routes|null = null;
|
||||
private modules_: NuxOnboardingModules;
|
||||
|
||||
// Default to false so view-manager is hidden until views are
|
||||
// initialized.
|
||||
protected modulesInitialized_: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.modules_ = {
|
||||
'new-user': loadTimeData.getString('newUserModules').split(','),
|
||||
'returning-user':
|
||||
loadTimeData.getString('returningUserModules').split(','),
|
||||
};
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
this.setAttribute('role', 'main');
|
||||
this.addEventListener(
|
||||
'default-browser-change', () => this.onDefaultBrowserChange_());
|
||||
|
||||
// Initiate focus-outline-manager for this document so that action-link
|
||||
// style can take advantage of it.
|
||||
FocusOutlineManager.forDocument(document);
|
||||
}
|
||||
|
||||
private onDefaultBrowserChange_() {
|
||||
this.shadowRoot!.querySelector('cr-toast')!.show();
|
||||
}
|
||||
|
||||
override onRouteChange(route: Routes, step: number) {
|
||||
const setStep = () => {
|
||||
// If the specified step doesn't exist, that means there are no more
|
||||
// steps. In that case, replace this page with NTP.
|
||||
if (!this.shadowRoot!.querySelector(`#step-${step}`)) {
|
||||
WelcomeBrowserProxyImpl.getInstance().goToNewTabPage(
|
||||
/* replace */ true);
|
||||
} else { // Otherwise, go to the chosen step of that route.
|
||||
// At this point, views are ready to be shown.
|
||||
this.modulesInitialized_ = true;
|
||||
this.$.viewManager.switchView(
|
||||
`step-${step}`, 'fade-in', 'no-animation');
|
||||
}
|
||||
};
|
||||
|
||||
// If the route changed, initialize the steps of modules for that route.
|
||||
if (this.currentRoute_ !== route) {
|
||||
this.initializeModules(route).then(setStep);
|
||||
} else {
|
||||
setStep();
|
||||
}
|
||||
|
||||
this.currentRoute_ = route;
|
||||
}
|
||||
|
||||
initializeModules(route: Routes) {
|
||||
// Remove all views except landing.
|
||||
this.$.viewManager
|
||||
.querySelectorAll('[slot="view"]:not([id="step-landing"])')
|
||||
.forEach(element => element.remove());
|
||||
|
||||
// If it is on landing route, end here.
|
||||
if (route === Routes.LANDING) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let modules = this.modules_[route];
|
||||
assert(modules); // Modules should be defined if on a valid route.
|
||||
const defaultBrowserPromise =
|
||||
NuxSetAsDefaultProxyImpl.getInstance()
|
||||
.requestDefaultBrowserState()
|
||||
.then((status) => {
|
||||
if (status.isDefault || !status.canBeDefault) {
|
||||
return false;
|
||||
} else if (!status.isDisabledByPolicy && !status.isUnknownError) {
|
||||
return true;
|
||||
} else { // Unknown error.
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Wait until the default-browser state and bookmark visibility are known
|
||||
// before anything initializes.
|
||||
return Promise
|
||||
.all([
|
||||
defaultBrowserPromise,
|
||||
BookmarkBarManager.getInstance().initialized,
|
||||
])
|
||||
.then(([canSetDefault]) => {
|
||||
modules = modules.filter(module => {
|
||||
if (module === 'nux-set-as-default') {
|
||||
return canSetDefault;
|
||||
}
|
||||
|
||||
if (!MODULES_WHITELIST.has(module)) {
|
||||
// Makes sure the module specified by the feature configuration is
|
||||
// whitelisted.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const indicatorElementCount = modules.reduce((count, module) => {
|
||||
return count += MODULES_NEEDING_INDICATOR.has(module) ? 1 : 0;
|
||||
}, 0);
|
||||
|
||||
let indicatorActiveCount = 0;
|
||||
modules.forEach((elementTagName, index) => {
|
||||
const element = document.createElement(elementTagName) as (
|
||||
NuxGoogleAppsElement | NuxNtpBackgroundElement |
|
||||
NuxSetAsDefaultElement);
|
||||
element.id = 'step-' + (index + 1);
|
||||
element.setAttribute('slot', 'view');
|
||||
if (MODULES_NEEDING_INDICATOR.has(elementTagName)) {
|
||||
element.indicatorModel = {
|
||||
total: indicatorElementCount,
|
||||
active: indicatorActiveCount++,
|
||||
};
|
||||
}
|
||||
this.$.viewManager.appendChild(element);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'welcome-app': WelcomeAppElement;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(WelcomeAppElement.is, WelcomeAppElement);
|
@ -1,48 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* @fileoverview A helper object used by the welcome page to interact with
|
||||
* the browser.
|
||||
*/
|
||||
export interface WelcomeBrowserProxy {
|
||||
/** @param redirectUrl the URL to go to, after signing in. */
|
||||
handleActivateSignIn(redirectUrl: string|null): void;
|
||||
|
||||
handleUserDecline(): void;
|
||||
goToNewTabPage(replace?: boolean): void;
|
||||
goToUrl(url: string): void;
|
||||
}
|
||||
|
||||
export class WelcomeBrowserProxyImpl implements WelcomeBrowserProxy {
|
||||
handleActivateSignIn(redirectUrl: string|null): void {
|
||||
chrome.send('handleActivateSignIn', redirectUrl ? [redirectUrl] : []);
|
||||
}
|
||||
|
||||
handleUserDecline(): void {
|
||||
chrome.send('handleUserDecline');
|
||||
}
|
||||
|
||||
goToNewTabPage(replace?: boolean): void {
|
||||
if (replace) {
|
||||
window.location.replace('chrome://newtab');
|
||||
} else {
|
||||
window.location.assign('chrome://newtab');
|
||||
}
|
||||
}
|
||||
|
||||
goToUrl(url: string): void {
|
||||
window.location.assign(url);
|
||||
}
|
||||
|
||||
static getInstance(): WelcomeBrowserProxy {
|
||||
return instance || (instance = new WelcomeBrowserProxyImpl());
|
||||
}
|
||||
|
||||
static setInstance(obj: WelcomeBrowserProxy) {
|
||||
instance = obj;
|
||||
}
|
||||
}
|
||||
|
||||
let instance: WelcomeBrowserProxy|null = null;
|
@ -10,8 +10,9 @@ std::array<GURL, kNtpBackgroundsCount> GetNtpBackgrounds() {
|
||||
// A set of whitelisted NTP background image URLs that are always considered
|
||||
// to be valid URLs that are shown to the user as part of the welcome flow.
|
||||
// These backgrounds were handpicked from the Backdrop API based on popularity
|
||||
// and those requiring minimum maintenance and translation work. This list
|
||||
// matches with chrome/browser/ui/webui/welcome/nux/ntp_background_handler.cc.
|
||||
// and those requiring minimum maintenance and translation work.
|
||||
// TODO(crbug.com/40253961): Remove this, since `chrome://welcome` has been
|
||||
// removed.
|
||||
const std::array<GURL, kNtpBackgroundsCount> kNtpBackgrounds = {{
|
||||
// Art
|
||||
GURL("https://lh5.googleusercontent.com/proxy/"
|
||||
|
@ -522,8 +522,6 @@ TEST_F(SearchEngineChoiceDialogServiceTest, IsUrlSuitableForDialog) {
|
||||
SearchEngineChoiceDialogServiceFactory::GetForProfile(profile());
|
||||
EXPECT_FALSE(search_engine_choice_service->IsUrlSuitableForDialog(
|
||||
GURL(chrome::kChromeUISettingsURL)));
|
||||
EXPECT_FALSE(search_engine_choice_service->IsUrlSuitableForDialog(
|
||||
GURL(chrome::kChromeUIWelcomeURL)));
|
||||
EXPECT_FALSE(search_engine_choice_service->IsUrlSuitableForDialog(
|
||||
GURL(chrome::kChromeUIDevToolsURL)));
|
||||
EXPECT_TRUE(search_engine_choice_service->IsUrlSuitableForDialog(
|
||||
|
@ -67,10 +67,9 @@ void ChromeSerializedNavigationDriver::Sanitize(
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
// Rewrite the old new tab and welcome page URLs to the new NTP URL.
|
||||
// Rewrite the old new tab URL to the new NTP URL.
|
||||
if (navigation->virtual_url().SchemeIs(content::kChromeUIScheme) &&
|
||||
(navigation->virtual_url().host_piece() == chrome::kChromeUIWelcomeHost ||
|
||||
navigation->virtual_url().host_piece() == chrome::kChromeUINewTabHost)) {
|
||||
navigation->virtual_url().host_piece() == chrome::kChromeUINewTabHost) {
|
||||
ChangeDestination(GURL(chrome::kChromeUINativeNewTabURL), navigation);
|
||||
}
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
@ -3238,24 +3238,6 @@ static_library("ui") {
|
||||
"webui/signin/dice_web_signin_intercept_ui.h",
|
||||
"webui/signin/inline_login_handler_impl.cc",
|
||||
"webui/signin/inline_login_handler_impl.h",
|
||||
"webui/welcome/bookmark_handler.cc",
|
||||
"webui/welcome/bookmark_handler.h",
|
||||
"webui/welcome/bookmark_item.cc",
|
||||
"webui/welcome/bookmark_item.h",
|
||||
"webui/welcome/google_apps_handler.cc",
|
||||
"webui/welcome/google_apps_handler.h",
|
||||
"webui/welcome/helpers.cc",
|
||||
"webui/welcome/helpers.h",
|
||||
"webui/welcome/ntp_background_fetcher.cc",
|
||||
"webui/welcome/ntp_background_fetcher.h",
|
||||
"webui/welcome/ntp_background_handler.cc",
|
||||
"webui/welcome/ntp_background_handler.h",
|
||||
"webui/welcome/set_as_default_handler.cc",
|
||||
"webui/welcome/set_as_default_handler.h",
|
||||
"webui/welcome/welcome_handler.cc",
|
||||
"webui/welcome/welcome_handler.h",
|
||||
"webui/welcome/welcome_ui.cc",
|
||||
"webui/welcome/welcome_ui.h",
|
||||
]
|
||||
|
||||
deps += [ "webui/signin/batch_upload:mojo_bindings" ]
|
||||
|
@ -370,26 +370,26 @@ IN_PROC_BROWSER_TEST_P(PrivacySandboxPromptHelperTestWithParam, UnsuitableUrl) {
|
||||
PromptOpenedForBrowser(browser(), testing::_))
|
||||
.Times(0);
|
||||
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition(
|
||||
browser(), GURL(chrome::kChromeUIWelcomeURL),
|
||||
WindowOpenDisposition::NEW_FOREGROUND_TAB,
|
||||
ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP));
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(
|
||||
browser(), https_test_server()->GetURL("a.test", "/title1.html")));
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(
|
||||
browser(),
|
||||
GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kAutofillSubPage)));
|
||||
int navigation_count = 3;
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
ASSERT_TRUE(
|
||||
ui_test_utils::NavigateToURL(browser(), GURL(ash::kChromeUIHelpAppURL)));
|
||||
navigation_count++;
|
||||
#endif
|
||||
std::vector<GURL> urls_to_open = {
|
||||
https_test_server()->GetURL("a.test", "/title1.html"),
|
||||
GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kAutofillSubPage),
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(
|
||||
browser(), GURL(chrome::kChromeUIOSSettingsURL)));
|
||||
navigation_count++;
|
||||
GURL(ash::kChromeUIHelpAppURL),
|
||||
GURL(chrome::kChromeUIOSSettingsURL),
|
||||
#endif
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < urls_to_open.size(); ++i) {
|
||||
if (i == 0) {
|
||||
// Open the first URL in a new tab to create a fresh new tab helper.
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition(
|
||||
browser(), urls_to_open[i], WindowOpenDisposition::NEW_FOREGROUND_TAB,
|
||||
ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP));
|
||||
} else {
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), urls_to_open[i]));
|
||||
}
|
||||
}
|
||||
|
||||
base::RunLoop().RunUntilIdle();
|
||||
histogram_tester.ExpectTotalCount(kPrivacySandboxDialogDisplayHostHistogram,
|
||||
0);
|
||||
@ -400,7 +400,7 @@ IN_PROC_BROWSER_TEST_P(PrivacySandboxPromptHelperTestWithParam, UnsuitableUrl) {
|
||||
1},
|
||||
{PrivacySandboxPromptHelper::SettingsPrivacySandboxPromptHelperEvent::
|
||||
kUrlNotSuitable,
|
||||
navigation_count}});
|
||||
urls_to_open.size()}});
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(PrivacySandboxPromptHelperTestWithParam,
|
||||
|
@ -1,157 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/policy/browser_signin_policy_handler.h"
|
||||
#include "chrome/browser/prefs/browser_prefs.h"
|
||||
#include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
|
||||
#include "chrome/browser/profiles/profile_attributes_init_params.h"
|
||||
#include "chrome/browser/profiles/profile_attributes_storage.h"
|
||||
#include "chrome/browser/profiles/profile_manager.h"
|
||||
#include "chrome/browser/search_engines/template_url_service_factory.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/test/base/testing_browser_process.h"
|
||||
#include "chrome/test/base/testing_profile.h"
|
||||
#include "components/policy/core/common/mock_policy_service.h"
|
||||
#include "components/policy/core/common/policy_map.h"
|
||||
#include "components/policy/policy_constants.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
class StartupBrowserPolicyUnitTest : public testing::Test {
|
||||
public:
|
||||
StartupBrowserPolicyUnitTest(const StartupBrowserPolicyUnitTest&) = delete;
|
||||
StartupBrowserPolicyUnitTest& operator=(const StartupBrowserPolicyUnitTest&) =
|
||||
delete;
|
||||
|
||||
protected:
|
||||
StartupBrowserPolicyUnitTest() = default;
|
||||
~StartupBrowserPolicyUnitTest() override = default;
|
||||
base::ScopedTempDir temp_dir_;
|
||||
|
||||
void SetUp() override {
|
||||
// Create a new temporary directory, and store the path
|
||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||
}
|
||||
|
||||
// Helper function to add a profile to |profile_manager|'s
|
||||
// ProfileAttributesStorage, and return the profile created.
|
||||
Profile* CreateTestingProfile(ProfileManager* profile_manager) {
|
||||
const std::string kProfileName = "Default";
|
||||
ProfileAttributesStorage& storage =
|
||||
profile_manager->GetProfileAttributesStorage();
|
||||
size_t num_profiles = storage.GetNumberOfProfiles();
|
||||
base::FilePath path = temp_dir_.GetPath().AppendASCII(kProfileName);
|
||||
ProfileAttributesInitParams params;
|
||||
params.profile_path = path;
|
||||
params.profile_name = base::ASCIIToUTF16(kProfileName.c_str());
|
||||
storage.AddProfile(std::move(params));
|
||||
EXPECT_EQ(num_profiles + 1u, storage.GetNumberOfProfiles());
|
||||
return profile_manager->GetProfile(path);
|
||||
}
|
||||
|
||||
// Helper function to set profile ephemeral.
|
||||
void SetProfileEphemeral(Profile* profile, bool val) {
|
||||
ProfileAttributesStorage& storage =
|
||||
g_browser_process->profile_manager()->GetProfileAttributesStorage();
|
||||
ProfileAttributesEntry* entry =
|
||||
storage.GetProfileAttributesWithPath(profile->GetPath());
|
||||
ASSERT_NE(entry, nullptr);
|
||||
entry->SetIsEphemeral(val);
|
||||
}
|
||||
|
||||
std::unique_ptr<policy::MockPolicyService> GetPolicyService(
|
||||
policy::PolicyMap& policy_map) {
|
||||
auto policy_service = std::make_unique<policy::MockPolicyService>();
|
||||
ON_CALL(*policy_service.get(), GetPolicies(testing::_))
|
||||
.WillByDefault(testing::ReturnRef(policy_map));
|
||||
return policy_service;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void SetPolicy(policy::PolicyMap& policy_map,
|
||||
const std::string& policy,
|
||||
Args... args) {
|
||||
policy_map.Set(policy, policy::POLICY_LEVEL_MANDATORY,
|
||||
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
|
||||
base::Value(args...), nullptr);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::unique_ptr<policy::PolicyMap> MakePolicy(const std::string& policy,
|
||||
Args... args) {
|
||||
auto policy_map = std::make_unique<policy::PolicyMap>();
|
||||
SetPolicy(*policy_map.get(), policy, args...);
|
||||
return policy_map;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(StartupBrowserPolicyUnitTest, BookmarkBarEnabled) {
|
||||
EXPECT_TRUE(welcome::CanShowGoogleAppModuleForTesting(policy::PolicyMap()));
|
||||
|
||||
auto policy_map = MakePolicy(policy::key::kBookmarkBarEnabled, true);
|
||||
EXPECT_TRUE(welcome::CanShowGoogleAppModuleForTesting(*policy_map));
|
||||
|
||||
policy_map = MakePolicy(policy::key::kBookmarkBarEnabled, false);
|
||||
EXPECT_FALSE(welcome::CanShowGoogleAppModuleForTesting(*policy_map));
|
||||
}
|
||||
|
||||
TEST_F(StartupBrowserPolicyUnitTest, EditBookmarksEnabled) {
|
||||
EXPECT_TRUE(welcome::CanShowGoogleAppModuleForTesting(policy::PolicyMap()));
|
||||
|
||||
auto policy_map = MakePolicy(policy::key::kEditBookmarksEnabled, true);
|
||||
EXPECT_TRUE(welcome::CanShowGoogleAppModuleForTesting(*policy_map));
|
||||
|
||||
policy_map = MakePolicy(policy::key::kEditBookmarksEnabled, false);
|
||||
EXPECT_FALSE(welcome::CanShowGoogleAppModuleForTesting(*policy_map));
|
||||
}
|
||||
|
||||
TEST_F(StartupBrowserPolicyUnitTest, DefaultBrowserSettingEnabled) {
|
||||
EXPECT_TRUE(welcome::CanShowSetDefaultModuleForTesting(policy::PolicyMap()));
|
||||
|
||||
auto policy_map =
|
||||
MakePolicy(policy::key::kDefaultBrowserSettingEnabled, true);
|
||||
EXPECT_TRUE(welcome::CanShowSetDefaultModuleForTesting(*policy_map));
|
||||
|
||||
policy_map = MakePolicy(policy::key::kDefaultBrowserSettingEnabled, false);
|
||||
EXPECT_FALSE(welcome::CanShowSetDefaultModuleForTesting(*policy_map));
|
||||
}
|
||||
|
||||
TEST_F(StartupBrowserPolicyUnitTest, BrowserSignin) {
|
||||
EXPECT_TRUE(welcome::CanShowSigninModuleForTesting(policy::PolicyMap()));
|
||||
|
||||
auto policy_map =
|
||||
MakePolicy(policy::key::kBrowserSignin,
|
||||
static_cast<int>(policy::BrowserSigninMode::kEnabled));
|
||||
EXPECT_TRUE(welcome::CanShowSigninModuleForTesting(*policy_map));
|
||||
|
||||
policy_map = MakePolicy(policy::key::kBrowserSignin,
|
||||
static_cast<int>(policy::BrowserSigninMode::kForced));
|
||||
EXPECT_TRUE(welcome::CanShowSigninModuleForTesting(*policy_map));
|
||||
|
||||
policy_map =
|
||||
MakePolicy(policy::key::kBrowserSignin,
|
||||
static_cast<int>(policy::BrowserSigninMode::kDisabled));
|
||||
EXPECT_FALSE(welcome::CanShowSigninModuleForTesting(*policy_map));
|
||||
}
|
||||
|
||||
TEST_F(StartupBrowserPolicyUnitTest, NewTabPageLocation) {
|
||||
policy::PolicyMap policy_map;
|
||||
TestingProfile::Builder builder;
|
||||
builder.SetPolicyService(GetPolicyService(policy_map));
|
||||
// Needed by the builder when building the profile.
|
||||
content::BrowserTaskEnvironment task_environment;
|
||||
auto profile = builder.Build();
|
||||
|
||||
TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
|
||||
profile.get(), base::BindRepeating(&CreateTemplateURLServiceForTesting));
|
||||
|
||||
EXPECT_TRUE(
|
||||
welcome::CanShowNTPBackgroundModuleForTesting(policy_map, profile.get()));
|
||||
|
||||
SetPolicy(policy_map, policy::key::kNewTabPageLocation, "https://crbug.com");
|
||||
EXPECT_FALSE(
|
||||
welcome::CanShowNTPBackgroundModuleForTesting(policy_map, profile.get()));
|
||||
}
|
@ -155,6 +155,20 @@ bool IsChromeControlledNtpUrl(const GURL& url) {
|
||||
}
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
bool IsWelcomePageUrl(const GURL& url) {
|
||||
static constexpr std::string_view kChromeUIWelcomeHost = "welcome";
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
static constexpr std::string_view kChromeUIWelcomeWin10Host = "welcome-win10";
|
||||
#endif
|
||||
|
||||
return url.SchemeIs(content::kChromeUIScheme) &&
|
||||
(url.host_piece() == kChromeUIWelcomeHost
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|| url.host_piece() == kChromeUIWelcomeWin10Host
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
StartupTabs StartupTabProviderImpl::GetDistributionFirstRunTabs(
|
||||
@ -277,12 +291,7 @@ StartupTabs StartupTabProviderImpl::GetInitialPrefsTabsForState(
|
||||
if (url.host_piece() == kNewTabUrlHost) {
|
||||
url = GURL(chrome::kChromeUINewTabURL);
|
||||
}
|
||||
if (url.SchemeIs(content::kChromeUIScheme) &&
|
||||
(url.host_piece() == chrome::kChromeUIWelcomeHost
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|| url.host_piece() == chrome::kChromeUIWelcomeWin10Host
|
||||
#endif
|
||||
)) {
|
||||
if (IsWelcomePageUrl(url)) {
|
||||
// These URLs are still referenced from some of the installers. As
|
||||
// these chrome UIs are removed, avoid opening tabs pointing to
|
||||
// invalid pages.
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
||||
#include "chrome/browser/ui/ui_features.h"
|
||||
#include "chrome/browser/ui/webui/theme_source.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "chrome/common/url_constants.h"
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
@ -196,12 +195,6 @@ class ChromeURLDataManagerWebUITrustedTypesTest
|
||||
enabled_features.push_back(whats_new::kForceEnabled);
|
||||
#endif
|
||||
|
||||
#if !BUILDFLAG(IS_CHROMEOS)
|
||||
if (GetParam() == std::string_view("chrome://welcome")) {
|
||||
enabled_features.push_back(welcome::kForceEnabled);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
enabled_features.push_back(ash::features::kDriveFsMirroring);
|
||||
enabled_features.push_back(ash::features::kShimlessRMAOsUpdate);
|
||||
@ -494,7 +487,6 @@ static constexpr const char* const kChromeUrls[] = {
|
||||
"chrome://browser-switch",
|
||||
"chrome://browser-switch/internals",
|
||||
"chrome://profile-picker",
|
||||
"chrome://welcome",
|
||||
#endif
|
||||
#if !BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// Note: Disabled because a DCHECK fires when directly visiting the URL.
|
||||
|
@ -166,7 +166,6 @@
|
||||
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
#include "chrome/browser/ui/webui/signin/batch_upload_ui.h"
|
||||
#include "chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.h"
|
||||
#include "chrome/browser/ui/webui/welcome/welcome_ui.h"
|
||||
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
|
||||
#if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
@ -376,7 +375,6 @@ void RegisterChromeWebUIConfigs() {
|
||||
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
map.AddWebUIConfig(std::make_unique<BatchUploadUIConfig>());
|
||||
map.AddWebUIConfig(std::make_unique<DiceWebSigninInterceptUIConfig>());
|
||||
map.AddWebUIConfig(std::make_unique<WelcomeUIConfig>());
|
||||
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
|
||||
#if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
@ -114,7 +114,6 @@
|
||||
|
||||
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
|
||||
#include "chrome/browser/ui/webui/app_home/app_home_ui.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
@ -146,11 +145,6 @@
|
||||
#include "extensions/common/manifest.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/browser/ui/webui/welcome/welcome_ui.h"
|
||||
#endif
|
||||
|
||||
using content::WebUI;
|
||||
using content::WebUIController;
|
||||
using ui::WebDialogUI;
|
||||
|
@ -1,8 +0,0 @@
|
||||
include_rules = [
|
||||
"+chrome/grit",
|
||||
"+components/bookmarks",
|
||||
"+components/grit",
|
||||
"+components/prefs",
|
||||
"+components/favicon",
|
||||
"+content/public/browser",
|
||||
]
|
@ -1,6 +0,0 @@
|
||||
monorail: {
|
||||
component: "UI>Browser>FirstRun"
|
||||
}
|
||||
buganizer_public: {
|
||||
component_id: 1457199
|
||||
}
|
@ -1 +0,0 @@
|
||||
johntlee@chromium.org
|
@ -1,48 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// 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/welcome/bookmark_handler.h"
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "chrome/grit/browser_resources.h"
|
||||
#include "components/bookmarks/common/bookmark_pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
BookmarkHandler::BookmarkHandler(PrefService* prefs) : prefs_(prefs) {}
|
||||
|
||||
BookmarkHandler::~BookmarkHandler() {}
|
||||
|
||||
void BookmarkHandler::RegisterMessages() {
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"toggleBookmarkBar",
|
||||
base::BindRepeating(&BookmarkHandler::HandleToggleBookmarkBar,
|
||||
base::Unretained(this)));
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"isBookmarkBarShown",
|
||||
base::BindRepeating(&BookmarkHandler::HandleIsBookmarkBarShown,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void BookmarkHandler::HandleToggleBookmarkBar(const base::Value::List& args) {
|
||||
CHECK(!args.empty());
|
||||
const bool show = args[0].GetBool();
|
||||
prefs_->SetBoolean(bookmarks::prefs::kShowBookmarkBar, show);
|
||||
}
|
||||
|
||||
void BookmarkHandler::HandleIsBookmarkBarShown(const base::Value::List& args) {
|
||||
AllowJavascript();
|
||||
|
||||
CHECK_EQ(1U, args.size());
|
||||
const base::Value& callback_id = args[0];
|
||||
|
||||
ResolveJavascriptCallback(
|
||||
callback_id,
|
||||
base::Value(prefs_->GetBoolean(bookmarks::prefs::kShowBookmarkBar)));
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,39 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_HANDLER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_HANDLER_H_
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/web_ui_message_handler.h"
|
||||
|
||||
class PrefService;
|
||||
|
||||
namespace welcome {
|
||||
|
||||
class BookmarkHandler : public content::WebUIMessageHandler {
|
||||
public:
|
||||
explicit BookmarkHandler(PrefService* prefs);
|
||||
|
||||
BookmarkHandler(const BookmarkHandler&) = delete;
|
||||
BookmarkHandler& operator=(const BookmarkHandler&) = delete;
|
||||
|
||||
~BookmarkHandler() override;
|
||||
|
||||
// WebUIMessageHandler:
|
||||
void RegisterMessages() override;
|
||||
|
||||
// Callbacks for JS APIs.
|
||||
void HandleToggleBookmarkBar(const base::Value::List& args);
|
||||
void HandleIsBookmarkBarShown(const base::Value::List& args);
|
||||
|
||||
private:
|
||||
// Weak reference.
|
||||
raw_ptr<PrefService> prefs_;
|
||||
};
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_HANDLER_H_
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// 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/welcome/bookmark_item.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/values.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
base::Value::List BookmarkItemsToListValue(
|
||||
base::span<const BookmarkItem> items) {
|
||||
base::Value::List list_value;
|
||||
for (const auto& item : items) {
|
||||
base::Value::Dict element;
|
||||
|
||||
element.Set("id", item.id);
|
||||
element.Set("name", item.name);
|
||||
element.Set("icon", item.webui_icon);
|
||||
element.Set("url", item.url);
|
||||
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
return list_value;
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_ITEM_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_ITEM_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/values.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
struct BookmarkItem {
|
||||
const int id;
|
||||
const std::string name;
|
||||
const char* webui_icon;
|
||||
const std::string url;
|
||||
const int icon; // Corresponds with resource ID, used for bookmark cache.
|
||||
};
|
||||
|
||||
base::Value::List BookmarkItemsToListValue(
|
||||
base::span<const BookmarkItem> items);
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_BOOKMARK_ITEM_H_
|
@ -1,141 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// 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/welcome/google_apps_handler.h"
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/metrics/field_trial_params.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "build/branding_buildflags.h"
|
||||
#include "chrome/browser/favicon/favicon_service_factory.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/ui/webui/welcome/bookmark_item.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/grit/chrome_unscaled_resources.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "chrome/grit/welcome_resources.h"
|
||||
#include "components/favicon/core/favicon_service.h"
|
||||
#include "components/grit/components_resources.h"
|
||||
#include "components/grit/components_scaled_resources.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_ui.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
// These values are persisted to logs. Entries should not be renumbered and
|
||||
// numeric values should never be reused.
|
||||
enum class GoogleApps {
|
||||
kGmail = 0,
|
||||
kYouTube = 1,
|
||||
kMaps = 2,
|
||||
kTranslate = 3,
|
||||
kNews = 4,
|
||||
kChromeWebStoreDoNotUse = 5, // Deprecated.
|
||||
kSearch = 6,
|
||||
kCount,
|
||||
};
|
||||
|
||||
const char* kGoogleAppsInteractionHistogram =
|
||||
"FirstRun.NewUserExperience.GoogleAppsInteraction";
|
||||
|
||||
constexpr const int kGoogleAppIconSize = 48; // Pixels.
|
||||
|
||||
GoogleAppsHandler::GoogleAppsHandler() {
|
||||
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
// Do not translate icon name as it is not human visible and needs to
|
||||
// match CSS.
|
||||
|
||||
BookmarkItem gmail = {
|
||||
static_cast<int>(GoogleApps::kGmail),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_GMAIL), "gmail",
|
||||
"https://accounts.google.com/b/0/AddMailService", IDS_WELCOME_GMAIL};
|
||||
|
||||
if (IsAppVariationEnabled()) {
|
||||
google_apps_.push_back({static_cast<int>(GoogleApps::kSearch),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_SEARCH),
|
||||
"search", "https://google.com",
|
||||
IDS_WELCOME_SEARCH});
|
||||
} else {
|
||||
google_apps_.push_back(gmail);
|
||||
}
|
||||
|
||||
google_apps_.push_back(
|
||||
{static_cast<int>(GoogleApps::kYouTube),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_APPS_YOUTUBE), "youtube",
|
||||
"https://youtube.com", IDS_WELCOME_YOUTUBE});
|
||||
|
||||
google_apps_.push_back(
|
||||
{static_cast<int>(GoogleApps::kMaps),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_APPS_MAPS), "maps",
|
||||
"https://maps.google.com", IDS_WELCOME_MAPS});
|
||||
|
||||
if (IsAppVariationEnabled()) {
|
||||
google_apps_.push_back(gmail);
|
||||
} else {
|
||||
google_apps_.push_back(
|
||||
{static_cast<int>(GoogleApps::kNews),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_APPS_NEWS), "news",
|
||||
"https://news.google.com", IDS_WELCOME_NEWS});
|
||||
}
|
||||
|
||||
google_apps_.push_back(
|
||||
{static_cast<int>(GoogleApps::kTranslate),
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_GOOGLE_APPS_TRANSLATE), "translate",
|
||||
"https://translate.google.com", IDS_WELCOME_TRANSLATE});
|
||||
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
}
|
||||
|
||||
GoogleAppsHandler::~GoogleAppsHandler() {}
|
||||
|
||||
void GoogleAppsHandler::RegisterMessages() {
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"cacheGoogleAppIcon",
|
||||
base::BindRepeating(&GoogleAppsHandler::HandleCacheGoogleAppIcon,
|
||||
base::Unretained(this)));
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"getGoogleAppsList",
|
||||
base::BindRepeating(&GoogleAppsHandler::HandleGetGoogleAppsList,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void GoogleAppsHandler::HandleCacheGoogleAppIcon(
|
||||
const base::Value::List& args) {
|
||||
CHECK_GE(args.size(), 1u);
|
||||
int app_id = args[0].GetInt();
|
||||
|
||||
const BookmarkItem* selectedApp = nullptr;
|
||||
for (const auto& google_app : google_apps_) {
|
||||
if (google_app.id == app_id) {
|
||||
selectedApp = &google_app;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CHECK(selectedApp); // WebUI should not be able to pass non-existent ID.
|
||||
|
||||
// Preload the favicon cache with Chrome-bundled images. Otherwise, the
|
||||
// pre-populated bookmarks don't have favicons and look bad. Favicons are
|
||||
// updated automatically when a user visits a site.
|
||||
GURL app_url = GURL(selectedApp->url);
|
||||
FaviconServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()),
|
||||
ServiceAccessType::EXPLICIT_ACCESS)
|
||||
->MergeFavicon(
|
||||
app_url, app_url, favicon_base::IconType::kFavicon,
|
||||
ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
|
||||
selectedApp->icon),
|
||||
gfx::Size(kGoogleAppIconSize, kGoogleAppIconSize));
|
||||
}
|
||||
|
||||
void GoogleAppsHandler::HandleGetGoogleAppsList(const base::Value::List& args) {
|
||||
AllowJavascript();
|
||||
CHECK_EQ(1U, args.size());
|
||||
const base::Value& callback_id = args[0];
|
||||
ResolveJavascriptCallback(callback_id,
|
||||
BookmarkItemsToListValue(google_apps_));
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_GOOGLE_APPS_HANDLER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_GOOGLE_APPS_HANDLER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/ui/webui/welcome/bookmark_item.h"
|
||||
#include "content/public/browser/web_ui_message_handler.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
extern const char* kGoogleAppsInteractionHistogram;
|
||||
|
||||
// These values are persisted to logs. Entries should not be renumbered and
|
||||
// numeric values should never be reused.
|
||||
enum class GoogleAppsInteraction {
|
||||
kPromptShown = 0,
|
||||
kNoThanks = 1,
|
||||
kGetStarted = 2,
|
||||
kCount,
|
||||
};
|
||||
|
||||
class GoogleAppsHandler : public content::WebUIMessageHandler {
|
||||
public:
|
||||
GoogleAppsHandler();
|
||||
|
||||
GoogleAppsHandler(const GoogleAppsHandler&) = delete;
|
||||
GoogleAppsHandler& operator=(const GoogleAppsHandler&) = delete;
|
||||
|
||||
~GoogleAppsHandler() override;
|
||||
|
||||
// WebUIMessageHandler:
|
||||
void RegisterMessages() override;
|
||||
|
||||
// Callbacks for JS APIs.
|
||||
void HandleCacheGoogleAppIcon(const base::Value::List& args);
|
||||
void HandleGetGoogleAppsList(const base::Value::List& args);
|
||||
|
||||
private:
|
||||
std::vector<BookmarkItem> google_apps_;
|
||||
};
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_GOOGLE_APPS_HANDLER_H_
|
@ -1,200 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// 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/welcome/helpers.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/metrics/field_trial_params.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/values.h"
|
||||
#include "build/branding_buildflags.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/policy/browser_signin_policy_handler.h"
|
||||
#include "chrome/browser/policy/profile_policy_connector.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/search/search.h"
|
||||
#include "components/policy/core/common/policy_map.h"
|
||||
#include "components/policy/policy_constants.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
// Available modules for both new and returning users.
|
||||
const char kDefaultNewUserModules[] =
|
||||
"nux-google-apps,nux-ntp-background,nux-set-as-default,signin-view";
|
||||
const char kDefaultReturningUserModules[] = "nux-set-as-default";
|
||||
|
||||
// Feature flag.
|
||||
BASE_FEATURE(kFeature, "NuxOnboarding", base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
// For testing purposes
|
||||
BASE_FEATURE(kForceEnabled,
|
||||
"NuxOnboardingForceEnabled",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
// The value of these FeatureParam values should be a comma-delimited list
|
||||
// of element names allowlisted in the MODULES_WHITELIST list, defined in
|
||||
// chrome/browser/resources/welcome/welcome_app.js
|
||||
const base::FeatureParam<std::string> kNewUserModules{
|
||||
&kFeature, "new-user-modules", kDefaultNewUserModules};
|
||||
const base::FeatureParam<std::string> kReturningUserModules{
|
||||
&kFeature, "returning-user-modules", kDefaultReturningUserModules};
|
||||
// For testing purposes
|
||||
const base::FeatureParam<std::string> kForceEnabledNewUserModules = {
|
||||
&kForceEnabled, "new-user-modules", kDefaultNewUserModules};
|
||||
const base::FeatureParam<std::string> kForceEnabledReturningUserModules = {
|
||||
&kForceEnabled, "returning-user-modules", kDefaultReturningUserModules};
|
||||
|
||||
// FeatureParam for app variation.
|
||||
const base::FeatureParam<bool> kShowGoogleApp{&kFeature,
|
||||
"app-variation-enabled", false};
|
||||
// For testing purposes
|
||||
const base::FeatureParam<bool> kForceEnabledShowGoogleApp = {
|
||||
&kForceEnabled, "app-variation-enabled", false};
|
||||
|
||||
bool IsPolicySetAndFalse(const policy::PolicyMap& policies,
|
||||
const std::string& policy_name) {
|
||||
const base::Value* policy =
|
||||
policies.GetValue(policy_name, base::Value::Type::BOOLEAN);
|
||||
return policy && !policy->GetBool();
|
||||
}
|
||||
|
||||
bool CanShowGoogleAppModule(const policy::PolicyMap& policies) {
|
||||
if (IsPolicySetAndFalse(policies, policy::key::kBookmarkBarEnabled))
|
||||
return false;
|
||||
|
||||
if (IsPolicySetAndFalse(policies, policy::key::kEditBookmarksEnabled))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanShowNTPBackgroundModule(const policy::PolicyMap& policies,
|
||||
Profile* profile) {
|
||||
// We can't set the background if the NTP is something other than Google.
|
||||
return !policies.GetValue(policy::key::kNewTabPageLocation,
|
||||
base::Value::Type::STRING) &&
|
||||
search::DefaultSearchProviderIsGoogle(profile);
|
||||
}
|
||||
|
||||
bool CanShowSetDefaultModule(const policy::PolicyMap& policies) {
|
||||
if (IsPolicySetAndFalse(policies, policy::key::kDefaultBrowserSettingEnabled))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanShowSigninModule(const policy::PolicyMap& policies) {
|
||||
const base::Value* browser_signin_value = policies.GetValue(
|
||||
policy::key::kBrowserSignin, base::Value::Type::INTEGER);
|
||||
|
||||
if (!browser_signin_value)
|
||||
return true;
|
||||
|
||||
return static_cast<policy::BrowserSigninMode>(
|
||||
browser_signin_value->GetInt()) !=
|
||||
policy::BrowserSigninMode::kDisabled;
|
||||
}
|
||||
|
||||
// Welcome experiments depend on Google being the default search provider.
|
||||
static bool CanExperimentWithVariations(Profile* profile) {
|
||||
return search::DefaultSearchProviderIsGoogle(profile);
|
||||
}
|
||||
|
||||
bool IsEnabled(Profile* profile) {
|
||||
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
return base::FeatureList::IsEnabled(welcome::kFeature) ||
|
||||
base::FeatureList::IsEnabled(welcome::kForceEnabled);
|
||||
#else
|
||||
// Allow enabling outside official builds for testing purposes.
|
||||
return base::FeatureList::IsEnabled(welcome::kForceEnabled);
|
||||
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
}
|
||||
|
||||
bool IsAppVariationEnabled() {
|
||||
return kForceEnabledShowGoogleApp.Get() || kShowGoogleApp.Get();
|
||||
}
|
||||
|
||||
const policy::PolicyMap& GetPoliciesFromProfile(Profile* profile) {
|
||||
policy::ProfilePolicyConnector* profile_connector =
|
||||
profile->GetProfilePolicyConnector();
|
||||
DCHECK(profile_connector);
|
||||
return profile_connector->policy_service()->GetPolicies(
|
||||
policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()));
|
||||
}
|
||||
|
||||
std::vector<std::string> GetAvailableModules(Profile* profile) {
|
||||
const policy::PolicyMap& policies = GetPoliciesFromProfile(profile);
|
||||
std::vector<std::string> available_modules;
|
||||
|
||||
if (CanShowGoogleAppModule(policies))
|
||||
available_modules.push_back("nux-google-apps");
|
||||
if (CanShowNTPBackgroundModule(policies, profile))
|
||||
available_modules.push_back("nux-ntp-background");
|
||||
if (CanShowSetDefaultModule(policies))
|
||||
available_modules.push_back("nux-set-as-default");
|
||||
if (CanShowSigninModule(policies))
|
||||
available_modules.push_back("signin-view");
|
||||
|
||||
return available_modules;
|
||||
}
|
||||
|
||||
std::string FilterModules(const std::string& requested_modules,
|
||||
const std::vector<std::string>& available_modules) {
|
||||
std::vector<std::string> filtered_modules;
|
||||
base::ranges::copy_if(
|
||||
base::SplitString(requested_modules, ",", base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY),
|
||||
std::back_inserter(filtered_modules),
|
||||
[&available_modules](const std::string& module) {
|
||||
return !module.empty() && base::Contains(available_modules, module);
|
||||
});
|
||||
return base::JoinString(filtered_modules, ",");
|
||||
}
|
||||
|
||||
base::Value::Dict GetModules(Profile* profile) {
|
||||
// This function should not be called when feature is not on.
|
||||
DCHECK(welcome::IsEnabled(profile));
|
||||
|
||||
std::string new_user_modules = kDefaultNewUserModules;
|
||||
std::string returning_user_modules = kDefaultReturningUserModules;
|
||||
|
||||
if (base::FeatureList::IsEnabled(welcome::kForceEnabled)) {
|
||||
new_user_modules = kForceEnabledNewUserModules.Get();
|
||||
returning_user_modules = kForceEnabledReturningUserModules.Get();
|
||||
} else if (CanExperimentWithVariations(profile)) {
|
||||
new_user_modules = kNewUserModules.Get();
|
||||
returning_user_modules = kReturningUserModules.Get();
|
||||
}
|
||||
|
||||
std::vector<std::string> available_modules = GetAvailableModules(profile);
|
||||
|
||||
base::Value::Dict modules;
|
||||
modules.Set("new-user", FilterModules(new_user_modules, available_modules));
|
||||
modules.Set("returning-user",
|
||||
FilterModules(returning_user_modules, available_modules));
|
||||
return modules;
|
||||
}
|
||||
|
||||
bool CanShowGoogleAppModuleForTesting(const policy::PolicyMap& policies) {
|
||||
return CanShowGoogleAppModule(policies);
|
||||
}
|
||||
|
||||
bool CanShowNTPBackgroundModuleForTesting(const policy::PolicyMap& policies,
|
||||
Profile* profile) {
|
||||
return CanShowNTPBackgroundModule(policies, profile);
|
||||
}
|
||||
|
||||
bool CanShowSetDefaultModuleForTesting(const policy::PolicyMap& policies) {
|
||||
return CanShowSetDefaultModule(policies);
|
||||
}
|
||||
|
||||
bool CanShowSigninModuleForTesting(const policy::PolicyMap& policies) {
|
||||
return CanShowSigninModule(policies);
|
||||
}
|
||||
} // namespace welcome
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2017 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_HELPERS_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_HELPERS_H_
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/values.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace policy {
|
||||
class PolicyMap;
|
||||
} // namespace policy
|
||||
|
||||
class Profile;
|
||||
|
||||
namespace welcome {
|
||||
|
||||
bool IsEnabled(Profile* profile);
|
||||
|
||||
bool IsAppVariationEnabled();
|
||||
|
||||
base::Value::Dict GetModules(Profile* profile);
|
||||
|
||||
// Exposed for testing.
|
||||
BASE_DECLARE_FEATURE(kForceEnabled);
|
||||
|
||||
bool CanShowGoogleAppModuleForTesting(const policy::PolicyMap& policies);
|
||||
bool CanShowNTPBackgroundModuleForTesting(const policy::PolicyMap& policies,
|
||||
Profile* profile);
|
||||
bool CanShowSetDefaultModuleForTesting(const policy::PolicyMap& policies);
|
||||
bool CanShowSigninModuleForTesting(const policy::PolicyMap& policies);
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_HELPERS_H_
|
@ -1,84 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// 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/welcome/ntp_background_fetcher.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/net/system_network_context_manager.h"
|
||||
#include "chrome/browser/search/background/ntp_backgrounds.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/cpp/simple_url_loader.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
NtpBackgroundFetcher::NtpBackgroundFetcher(
|
||||
size_t index,
|
||||
content::WebUIDataSource::GotDataCallback callback)
|
||||
: index_(index), callback_(std::move(callback)) {
|
||||
DCHECK(callback_);
|
||||
net::NetworkTrafficAnnotationTag traffic_annotation =
|
||||
net::DefineNetworkTrafficAnnotation("nux_ntp_background_preview", R"(
|
||||
semantics {
|
||||
sender: "Navi Onboarding NTP background module"
|
||||
description:
|
||||
"As part of the Navi Onboarding flow, the NTP background module "
|
||||
"allows users to preview what a custom background for the "
|
||||
"New Tab Page would look like. The list of available backgrounds "
|
||||
"is manually whitelisted."
|
||||
trigger:
|
||||
"The user selects an image to preview."
|
||||
data:
|
||||
"User-selected image URL."
|
||||
destination: GOOGLE_OWNED_SERVICE
|
||||
}
|
||||
policy {
|
||||
cookies_allowed: NO
|
||||
setting:
|
||||
"This feature cannot be disabled by settings, but it is only "
|
||||
"triggered by a user action."
|
||||
policy_exception_justification: "Not implemented."
|
||||
})");
|
||||
|
||||
auto backgrounds = GetNtpBackgrounds();
|
||||
|
||||
if (index_ >= backgrounds.size()) {
|
||||
OnFetchCompleted(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
GURL url = backgrounds[index_];
|
||||
auto resource_request = std::make_unique<network::ResourceRequest>();
|
||||
resource_request->url = url;
|
||||
resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
|
||||
simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
|
||||
traffic_annotation);
|
||||
|
||||
network::mojom::URLLoaderFactory* loader_factory =
|
||||
g_browser_process->system_network_context_manager()
|
||||
->GetURLLoaderFactory();
|
||||
simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
|
||||
loader_factory, base::BindOnce(&NtpBackgroundFetcher::OnFetchCompleted,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
NtpBackgroundFetcher::~NtpBackgroundFetcher() = default;
|
||||
|
||||
void NtpBackgroundFetcher::OnFetchCompleted(
|
||||
std::unique_ptr<std::string> response_body) {
|
||||
if (response_body) {
|
||||
std::move(callback_).Run(base::MakeRefCounted<base::RefCountedString>(
|
||||
std::move(*response_body)));
|
||||
} else {
|
||||
std::move(callback_).Run(base::MakeRefCounted<base::RefCountedBytes>());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_FETCHER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_FETCHER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
|
||||
namespace network {
|
||||
class SimpleURLLoader;
|
||||
}
|
||||
|
||||
namespace welcome {
|
||||
|
||||
class NtpBackgroundFetcher {
|
||||
public:
|
||||
NtpBackgroundFetcher(size_t index,
|
||||
content::WebUIDataSource::GotDataCallback callback);
|
||||
|
||||
NtpBackgroundFetcher(const NtpBackgroundFetcher&) = delete;
|
||||
NtpBackgroundFetcher& operator=(const NtpBackgroundFetcher&) = delete;
|
||||
|
||||
~NtpBackgroundFetcher();
|
||||
|
||||
private:
|
||||
void OnFetchCompleted(std::unique_ptr<std::string> response_body);
|
||||
|
||||
size_t index_;
|
||||
content::WebUIDataSource::GotDataCallback callback_;
|
||||
std::unique_ptr<network::SimpleURLLoader> simple_loader_;
|
||||
};
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_FETCHER_H_
|
@ -1,174 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// 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/welcome/ntp_background_handler.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/search/background/ntp_backgrounds.h"
|
||||
#include "chrome/browser/search/background/ntp_custom_background_service.h"
|
||||
#include "chrome/browser/search/background/ntp_custom_background_service_factory.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "chrome/grit/welcome_resources.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "content/public/browser/web_ui.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
enum class NtpBackgrounds {
|
||||
kArt = 0,
|
||||
kCityscape = 1,
|
||||
kEarth = 2,
|
||||
kGeometricShapes = 3,
|
||||
kLandscape = 4,
|
||||
};
|
||||
|
||||
NtpBackgroundHandler::NtpBackgroundHandler() {}
|
||||
NtpBackgroundHandler::~NtpBackgroundHandler() {}
|
||||
|
||||
void NtpBackgroundHandler::RegisterMessages() {
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"clearBackground",
|
||||
base::BindRepeating(&NtpBackgroundHandler::HandleClearBackground,
|
||||
base::Unretained(this)));
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"getBackgrounds",
|
||||
base::BindRepeating(&NtpBackgroundHandler::HandleGetBackgrounds,
|
||||
base::Unretained(this)));
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"setBackground",
|
||||
base::BindRepeating(&NtpBackgroundHandler::HandleSetBackground,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void NtpBackgroundHandler::HandleClearBackground(
|
||||
const base::Value::List& args) {
|
||||
auto* service = NtpCustomBackgroundServiceFactory::GetForProfile(
|
||||
Profile::FromWebUI(web_ui()));
|
||||
service->ResetCustomBackgroundInfo();
|
||||
}
|
||||
|
||||
void NtpBackgroundHandler::HandleGetBackgrounds(const base::Value::List& args) {
|
||||
AllowJavascript();
|
||||
CHECK_EQ(1U, args.size());
|
||||
const base::Value& callback_id = args[0];
|
||||
|
||||
base::Value::List list_value;
|
||||
std::array<GURL, kNtpBackgroundsCount> NtpBackgrounds = GetNtpBackgrounds();
|
||||
const std::string kUrlPrefix = "preview-background.jpg?";
|
||||
|
||||
{
|
||||
base::Value::Dict element;
|
||||
int id = static_cast<int>(NtpBackgrounds::kEarth);
|
||||
element.Set("id", id);
|
||||
element.Set("title", l10n_util::GetStringUTF8(
|
||||
IDS_WELCOME_NTP_BACKGROUND_EARTH_TITLE));
|
||||
element.Set("imageUrl", kUrlPrefix + base::NumberToString(id));
|
||||
element.Set("thumbnailClass", "earth");
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
{
|
||||
base::Value::Dict element;
|
||||
int id = static_cast<int>(NtpBackgrounds::kCityscape);
|
||||
element.Set("id", id);
|
||||
element.Set("title", l10n_util::GetStringUTF8(
|
||||
IDS_WELCOME_NTP_BACKGROUND_CITYSCAPE_TITLE));
|
||||
element.Set("imageUrl", kUrlPrefix + base::NumberToString(id));
|
||||
element.Set("thumbnailClass", "cityscape");
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
{
|
||||
base::Value::Dict element;
|
||||
int id = static_cast<int>(NtpBackgrounds::kLandscape);
|
||||
element.Set("id", id);
|
||||
element.Set("title", l10n_util::GetStringUTF8(
|
||||
IDS_WELCOME_NTP_BACKGROUND_LANDSCAPE_TITLE));
|
||||
element.Set("imageUrl", kUrlPrefix + base::NumberToString(id));
|
||||
element.Set("thumbnailClass", "landscape");
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
{
|
||||
base::Value::Dict element;
|
||||
int id = static_cast<int>(NtpBackgrounds::kArt);
|
||||
element.Set("id", id);
|
||||
element.Set("title",
|
||||
l10n_util::GetStringUTF8(IDS_WELCOME_NTP_BACKGROUND_ART_TITLE));
|
||||
element.Set("imageUrl", kUrlPrefix + base::NumberToString(id));
|
||||
element.Set("thumbnailClass", "art");
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
{
|
||||
base::Value::Dict element;
|
||||
int id = static_cast<int>(NtpBackgrounds::kGeometricShapes);
|
||||
element.Set("id", id);
|
||||
element.Set("title",
|
||||
l10n_util::GetStringUTF8(
|
||||
IDS_WELCOME_NTP_BACKGROUND_GEOMETRIC_SHAPES_TITLE));
|
||||
element.Set("imageUrl", kUrlPrefix + base::NumberToString(id));
|
||||
element.Set("thumbnailClass", "geometric-shapes");
|
||||
list_value.Append(std::move(element));
|
||||
}
|
||||
|
||||
ResolveJavascriptCallback(callback_id, list_value);
|
||||
}
|
||||
|
||||
void NtpBackgroundHandler::HandleSetBackground(const base::Value::List& args) {
|
||||
CHECK_EQ(1U, args.size());
|
||||
int background_index = args[0].GetInt();
|
||||
|
||||
std::array<GURL, kNtpBackgroundsCount> NtpBackgrounds = GetNtpBackgrounds();
|
||||
auto* service = NtpCustomBackgroundServiceFactory::GetForProfile(
|
||||
Profile::FromWebUI(web_ui()));
|
||||
|
||||
switch (background_index) {
|
||||
case static_cast<int>(NtpBackgrounds::kArt):
|
||||
service->SetCustomBackgroundInfo(NtpBackgrounds[background_index], GURL(),
|
||||
"Universe Cosmic Vacum",
|
||||
"Philipp Rietz — Walli", GURL(), "");
|
||||
break;
|
||||
case static_cast<int>(NtpBackgrounds::kCityscape):
|
||||
service->SetCustomBackgroundInfo(
|
||||
NtpBackgrounds[background_index], GURL(),
|
||||
l10n_util::GetStringFUTF8(IDS_WELCOME_NTP_BACKGROUND_PHOTO_BY_LABEL,
|
||||
u"Ev Tchebotarev"),
|
||||
"",
|
||||
GURL("https://500px.com/photo/135751035/"
|
||||
"soulseek-by-%E5%B0%A4%E9%87%91%E5%B0%BC-ev-tchebotarev"),
|
||||
"");
|
||||
break;
|
||||
case static_cast<int>(NtpBackgrounds::kEarth):
|
||||
service->SetCustomBackgroundInfo(
|
||||
NtpBackgrounds[background_index], GURL(),
|
||||
l10n_util::GetStringFUTF8(IDS_WELCOME_NTP_BACKGROUND_PHOTO_BY_LABEL,
|
||||
u"NASA Image Library"),
|
||||
"", GURL("https://www.google.com/sky/"), "");
|
||||
break;
|
||||
case static_cast<int>(NtpBackgrounds::kGeometricShapes):
|
||||
service->SetCustomBackgroundInfo(NtpBackgrounds[background_index], GURL(),
|
||||
"Tessellation 15", "Justin Prno — Walli",
|
||||
GURL(), "");
|
||||
break;
|
||||
case static_cast<int>(NtpBackgrounds::kLandscape):
|
||||
service->SetCustomBackgroundInfo(
|
||||
NtpBackgrounds[background_index], GURL(),
|
||||
l10n_util::GetStringFUTF8(IDS_WELCOME_NTP_BACKGROUND_PHOTO_BY_LABEL,
|
||||
u"Giulio Rosso Chioso"),
|
||||
"",
|
||||
GURL("https://500px.com/photo/41149196/"
|
||||
"le-piscine-sunset-by-giulio-rosso-chioso"),
|
||||
"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_HANDLER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_HANDLER_H_
|
||||
|
||||
#include "content/public/browser/web_ui_message_handler.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
class NtpBackgroundHandler : public content::WebUIMessageHandler {
|
||||
public:
|
||||
NtpBackgroundHandler();
|
||||
|
||||
NtpBackgroundHandler(const NtpBackgroundHandler&) = delete;
|
||||
NtpBackgroundHandler& operator=(const NtpBackgroundHandler&) = delete;
|
||||
|
||||
~NtpBackgroundHandler() override;
|
||||
|
||||
// WebUIMessageHandler:
|
||||
void RegisterMessages() override;
|
||||
|
||||
// Callbacks for JS APIs.
|
||||
void HandleClearBackground(const base::Value::List& args);
|
||||
void HandleGetBackgrounds(const base::Value::List& args);
|
||||
void HandleSetBackground(const base::Value::List& args);
|
||||
};
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_NTP_BACKGROUND_HANDLER_H_
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// 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/welcome/set_as_default_handler.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
SetAsDefaultHandler::SetAsDefaultHandler()
|
||||
: settings::DefaultBrowserHandler() {}
|
||||
|
||||
SetAsDefaultHandler::~SetAsDefaultHandler() {}
|
||||
|
||||
void SetAsDefaultHandler::RecordSetAsDefaultUMA() {
|
||||
// TODO(hcarmona): Add UMA tracking.
|
||||
}
|
||||
|
||||
} // namespace welcome
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_SET_AS_DEFAULT_HANDLER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_SET_AS_DEFAULT_HANDLER_H_
|
||||
|
||||
#include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h"
|
||||
|
||||
namespace welcome {
|
||||
|
||||
class SetAsDefaultHandler : public settings::DefaultBrowserHandler {
|
||||
public:
|
||||
SetAsDefaultHandler();
|
||||
|
||||
SetAsDefaultHandler(const SetAsDefaultHandler&) = delete;
|
||||
SetAsDefaultHandler& operator=(const SetAsDefaultHandler&) = delete;
|
||||
|
||||
~SetAsDefaultHandler() override;
|
||||
|
||||
protected:
|
||||
void RecordSetAsDefaultUMA() override;
|
||||
};
|
||||
|
||||
} // namespace welcome
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_SET_AS_DEFAULT_HANDLER_H_
|
@ -1,118 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// 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/welcome/welcome_handler.h"
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/metrics/user_metrics.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/signin/identity_manager_factory.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/browser_finder.h"
|
||||
#include "chrome/browser/ui/browser_navigator.h"
|
||||
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
|
||||
#include "chrome/common/url_constants.h"
|
||||
#include "components/signin/public/base/signin_metrics.h"
|
||||
#include "components/signin/public/identity_manager/identity_manager.h"
|
||||
#include "ui/base/page_transition_types.h"
|
||||
|
||||
const char kWelcomeReturningUserUrl[] = "chrome://welcome/returning-user";
|
||||
|
||||
WelcomeHandler::WelcomeHandler(content::WebUI* web_ui)
|
||||
: profile_(Profile::FromWebUI(web_ui)),
|
||||
result_(WelcomeResult::DEFAULT),
|
||||
is_redirected_welcome_impression_(false) {
|
||||
}
|
||||
|
||||
WelcomeHandler::~WelcomeHandler() {
|
||||
// If this instance is spawned due to being redirected back to welcome page
|
||||
// by the onboarding logic, there's no need to log sign-in metrics again.
|
||||
if (is_redirected_welcome_impression_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We log that an impression occurred at destruct-time. This can't be done at
|
||||
// construct-time on some platforms because this page is shown immediately
|
||||
// after a new installation of Chrome and loads while the user is deciding
|
||||
// whether or not to opt in to logging.
|
||||
signin_metrics::RecordSigninImpressionUserActionForAccessPoint(
|
||||
signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE);
|
||||
|
||||
}
|
||||
|
||||
bool WelcomeHandler::isValidRedirectUrl() {
|
||||
GURL current_url = web_ui()->GetWebContents()->GetVisibleURL();
|
||||
|
||||
return current_url == kWelcomeReturningUserUrl;
|
||||
}
|
||||
|
||||
// Handles backend events necessary when user clicks "Sign in."
|
||||
void WelcomeHandler::HandleActivateSignIn(const base::Value::List& args) {
|
||||
result_ = WelcomeResult::STARTED_SIGN_IN;
|
||||
base::RecordAction(base::UserMetricsAction("WelcomePage_SignInClicked"));
|
||||
|
||||
if (IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount(
|
||||
signin::ConsentLevel::kSync)) {
|
||||
// In general, this page isn't shown to signed-in users; however, if one
|
||||
// should arrive here, then opening the sign-in dialog will likely lead
|
||||
// to a crash. Thus, we just act like sign-in was "successful" and whisk
|
||||
// them away to the NTP instead.
|
||||
GoToNewTabPage();
|
||||
} else {
|
||||
GURL redirect_url(chrome::kChromeUINewTabURL);
|
||||
if (args.size() == 1U) {
|
||||
const std::string& url_string = args[0].GetString();
|
||||
redirect_url = GURL(url_string);
|
||||
DCHECK(redirect_url.is_valid());
|
||||
}
|
||||
|
||||
Browser* browser = GetBrowser();
|
||||
browser->signin_view_controller()->ShowSignin(
|
||||
signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE, redirect_url);
|
||||
}
|
||||
}
|
||||
|
||||
// Handles backend events necessary when user clicks "Get started."
|
||||
void WelcomeHandler::HandleUserDecline(const base::Value::List& args) {
|
||||
result_ = WelcomeResult::DECLINED_SIGN_IN;
|
||||
GoToNewTabPage();
|
||||
}
|
||||
|
||||
// Override from WebUIMessageHandler.
|
||||
void WelcomeHandler::RegisterMessages() {
|
||||
// Check if this instance of WelcomeHandler is spawned by welcome flow
|
||||
// redirecting users back to welcome page. This is done here instead of
|
||||
// constructor, because web_ui hasn't loaded yet at that time.
|
||||
is_redirected_welcome_impression_ = isValidRedirectUrl();
|
||||
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"handleActivateSignIn",
|
||||
base::BindRepeating(&WelcomeHandler::HandleActivateSignIn,
|
||||
base::Unretained(this)));
|
||||
web_ui()->RegisterMessageCallback(
|
||||
"handleUserDecline",
|
||||
base::BindRepeating(&WelcomeHandler::HandleUserDecline,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void WelcomeHandler::GoToNewTabPage() {
|
||||
WelcomeHandler::GoToURL(GURL(chrome::kChromeUINewTabURL));
|
||||
}
|
||||
|
||||
void WelcomeHandler::GoToURL(GURL url) {
|
||||
NavigateParams params(GetBrowser(), url,
|
||||
ui::PageTransition::PAGE_TRANSITION_LINK);
|
||||
params.source_contents = web_ui()->GetWebContents();
|
||||
Navigate(¶ms);
|
||||
}
|
||||
|
||||
Browser* WelcomeHandler::GetBrowser() {
|
||||
DCHECK(web_ui());
|
||||
content::WebContents* contents = web_ui()->GetWebContents();
|
||||
DCHECK(contents);
|
||||
Browser* browser = chrome::FindBrowserWithTab(contents);
|
||||
DCHECK(browser);
|
||||
return browser;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
|
||||
#include "content/public/browser/web_ui_message_handler.h"
|
||||
|
||||
class Browser;
|
||||
class Profile;
|
||||
class GURL;
|
||||
|
||||
// Handles actions on Welcome page.
|
||||
class WelcomeHandler : public content::WebUIMessageHandler {
|
||||
public:
|
||||
explicit WelcomeHandler(content::WebUI* web_ui);
|
||||
|
||||
WelcomeHandler(const WelcomeHandler&) = delete;
|
||||
WelcomeHandler& operator=(const WelcomeHandler&) = delete;
|
||||
|
||||
~WelcomeHandler() override;
|
||||
|
||||
// content::WebUIMessageHandler:
|
||||
void RegisterMessages() override;
|
||||
|
||||
private:
|
||||
enum WelcomeResult {
|
||||
// User navigated away from page.
|
||||
DEFAULT = 0,
|
||||
// User clicked the "Get Started" button.
|
||||
DECLINED_SIGN_IN = 1,
|
||||
// DEPRECATED: User completed sign-in flow.
|
||||
// SIGNED_IN = 2,
|
||||
// DEPRECATED: User attempted sign-in flow, then navigated away.
|
||||
// ATTEMPTED = 3,
|
||||
// DEPRECATED: User attempted sign-in flow, then clicked "No Thanks."
|
||||
// ATTEMPTED_DECLINED = 4,
|
||||
// User started the sign-in flow.
|
||||
STARTED_SIGN_IN = 5,
|
||||
// New results must be added before this line, and should correspond to
|
||||
// values in tools/metrics/histograms/enums.xml.
|
||||
WELCOME_RESULT_MAX
|
||||
};
|
||||
|
||||
void HandleActivateSignIn(const base::Value::List& args);
|
||||
void HandleUserDecline(const base::Value::List& args);
|
||||
void GoToNewTabPage();
|
||||
void GoToURL(GURL url);
|
||||
bool isValidRedirectUrl();
|
||||
|
||||
Browser* GetBrowser();
|
||||
|
||||
raw_ptr<Profile> profile_;
|
||||
WelcomeResult result_;
|
||||
|
||||
// Indicates whether this WelcomeHandler instance is spawned due to users
|
||||
// being redirected back to welcome page as part of the onboarding flow.
|
||||
bool is_redirected_welcome_impression_;
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_
|
@ -1,207 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// 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/welcome/welcome_ui.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/values.h"
|
||||
#include "build/branding_buildflags.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/signin/account_consistency_mode_manager.h"
|
||||
#include "chrome/browser/ui/webui/webui_util.h"
|
||||
#include "chrome/browser/ui/webui/welcome/bookmark_handler.h"
|
||||
#include "chrome/browser/ui/webui/welcome/google_apps_handler.h"
|
||||
#include "chrome/browser/ui/webui/welcome/helpers.h"
|
||||
#include "chrome/browser/ui/webui/welcome/ntp_background_fetcher.h"
|
||||
#include "chrome/browser/ui/webui/welcome/ntp_background_handler.h"
|
||||
#include "chrome/browser/ui/webui/welcome/set_as_default_handler.h"
|
||||
#include "chrome/browser/ui/webui/welcome/welcome_handler.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "chrome/grit/branded_strings.h"
|
||||
#include "chrome/grit/chrome_unscaled_resources.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "chrome/grit/welcome_resources.h"
|
||||
#include "chrome/grit/welcome_resources_map.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/signin/public/base/signin_pref_names.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/web_ui_controller.h"
|
||||
#include "net/base/url_util.h"
|
||||
#include "ui/base/webui/web_ui_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const char kPreviewBackgroundPath[] = "preview-background.jpg";
|
||||
|
||||
bool ShouldHandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,
|
||||
const std::string& path) {
|
||||
if (!base::StartsWith(path, kPreviewBackgroundPath,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string index_param = path.substr(path.find_first_of("?") + 1);
|
||||
int background_index = -1;
|
||||
if (!base::StringToInt(index_param, &background_index) ||
|
||||
background_index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!weak_ptr;
|
||||
}
|
||||
|
||||
void HandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,
|
||||
const std::string& path,
|
||||
content::WebUIDataSource::GotDataCallback callback) {
|
||||
DCHECK(ShouldHandleRequestCallback(weak_ptr, path));
|
||||
|
||||
std::string index_param = path.substr(path.find_first_of("?") + 1);
|
||||
int background_index = -1;
|
||||
CHECK(base::StringToInt(index_param, &background_index) ||
|
||||
background_index < 0);
|
||||
|
||||
DCHECK(weak_ptr);
|
||||
weak_ptr->CreateBackgroundFetcher(background_index, std::move(callback));
|
||||
}
|
||||
|
||||
void AddStrings(content::WebUIDataSource* html_source) {
|
||||
static constexpr webui::LocalizedString kLocalizedStrings[] = {
|
||||
// Shared strings.
|
||||
{"bookmarkAdded", IDS_WELCOME_BOOKMARK_ADDED},
|
||||
{"bookmarksAdded", IDS_WELCOME_BOOKMARKS_ADDED},
|
||||
{"bookmarkRemoved", IDS_WELCOME_BOOKMARK_REMOVED},
|
||||
{"bookmarksRemoved", IDS_WELCOME_BOOKMARKS_REMOVED},
|
||||
{"defaultBrowserChanged", IDS_DEFAULT_BROWSER_CHANGED},
|
||||
{"headerText", IDS_WELCOME_HEADER},
|
||||
{"next", IDS_WELCOME_NEXT},
|
||||
{"noThanks", IDS_NO_THANKS},
|
||||
{"skip", IDS_WELCOME_SKIP},
|
||||
{"stepsLabel", IDS_WELCOME_STEPS},
|
||||
|
||||
// Sign-in view strings.
|
||||
{"signInHeader", IDS_WELCOME_SIGNIN_VIEW_HEADER},
|
||||
{"signInSubHeader", IDS_WELCOME_SIGNIN_VIEW_SUB_HEADER},
|
||||
{"signIn", IDS_WELCOME_SIGNIN_VIEW_SIGNIN},
|
||||
|
||||
// Google apps module strings.
|
||||
{"googleAppsDescription", IDS_WELCOME_GOOGLE_APPS_DESCRIPTION},
|
||||
|
||||
// New Tab Page background module strings.
|
||||
{"ntpBackgroundDescription", IDS_WELCOME_NTP_BACKGROUND_DESCRIPTION},
|
||||
{"ntpBackgroundDefault", IDS_WELCOME_NTP_BACKGROUND_DEFAULT_TITLE},
|
||||
{"ntpBackgroundPreviewUpdated",
|
||||
IDS_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED},
|
||||
{"ntpBackgroundReset", IDS_WELCOME_NTP_BACKGROUND_RESET},
|
||||
|
||||
// Set as default module strings.
|
||||
{"setDefaultHeader", IDS_WELCOME_SET_AS_DEFAULT_HEADER},
|
||||
{"setDefaultSubHeader", IDS_WELCOME_SET_AS_DEFAULT_SUB_HEADER},
|
||||
{"setDefaultConfirm", IDS_WELCOME_SET_AS_DEFAULT_SET_AS_DEFAULT},
|
||||
|
||||
// Landing view strings.
|
||||
{"landingTitle", IDS_WELCOME_LANDING_TITLE},
|
||||
{"landingDescription", IDS_WELCOME_LANDING_DESCRIPTION},
|
||||
{"landingNewUser", IDS_WELCOME_LANDING_NEW_USER},
|
||||
{"landingExistingUser", IDS_WELCOME_LANDING_EXISTING_USER},
|
||||
{"landingPauseAnimations", IDS_WELCOME_LANDING_PAUSE_ANIMATIONS},
|
||||
{"landingPlayAnimations", IDS_WELCOME_LANDING_PLAY_ANIMATIONS},
|
||||
};
|
||||
html_source->AddLocalizedStrings(kLocalizedStrings);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool WelcomeUIConfig::IsWebUIEnabled(content::BrowserContext* browser_context) {
|
||||
Profile* profile = Profile::FromBrowserContext(browser_context);
|
||||
return welcome::IsEnabled(profile);
|
||||
}
|
||||
|
||||
std::unique_ptr<content::WebUIController>
|
||||
WelcomeUIConfig::CreateWebUIController(content::WebUI* web_ui,
|
||||
const GURL& url) {
|
||||
return std::make_unique<WelcomeUI>(web_ui, url);
|
||||
}
|
||||
|
||||
WelcomeUI::WelcomeUI(content::WebUI* web_ui, const GURL& url)
|
||||
: content::WebUIController(web_ui) {
|
||||
Profile* profile = Profile::FromWebUI(web_ui);
|
||||
|
||||
// This page is not shown to incognito or guest profiles. If one should end up
|
||||
// here, we return, causing a 404-like page.
|
||||
if (!profile || profile->IsOffTheRecord()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StorePageSeen(profile);
|
||||
|
||||
web_ui->AddMessageHandler(std::make_unique<WelcomeHandler>(web_ui));
|
||||
|
||||
content::WebUIDataSource* html_source =
|
||||
content::WebUIDataSource::CreateAndAdd(profile, url.host());
|
||||
webui::SetupWebUIDataSource(html_source, base::span(kWelcomeResources),
|
||||
IDR_WELCOME_WELCOME_HTML);
|
||||
|
||||
// Add welcome strings.
|
||||
AddStrings(html_source);
|
||||
|
||||
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
html_source->AddResourcePath("images/background_svgs/logo.svg",
|
||||
IDR_PRODUCT_LOGO_128PX_SVG);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
html_source->AddBoolean("is_win10", true);
|
||||
#endif
|
||||
|
||||
// Add the shared bookmark handler for welcome modules.
|
||||
web_ui->AddMessageHandler(
|
||||
std::make_unique<welcome::BookmarkHandler>(profile->GetPrefs()));
|
||||
|
||||
// Add google apps bookmarking module.
|
||||
web_ui->AddMessageHandler(std::make_unique<welcome::GoogleAppsHandler>());
|
||||
|
||||
// Add NTP custom background module.
|
||||
web_ui->AddMessageHandler(std::make_unique<welcome::NtpBackgroundHandler>());
|
||||
|
||||
// Add set-as-default module.
|
||||
web_ui->AddMessageHandler(std::make_unique<welcome::SetAsDefaultHandler>());
|
||||
|
||||
html_source->AddString(
|
||||
"newUserModules",
|
||||
welcome::GetModules(profile).Find("new-user")->GetString());
|
||||
html_source->AddString(
|
||||
"returningUserModules",
|
||||
welcome::GetModules(profile).Find("returning-user")->GetString());
|
||||
html_source->AddBoolean(
|
||||
"signinAllowed", profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
|
||||
html_source->SetRequestFilter(
|
||||
base::BindRepeating(&ShouldHandleRequestCallback,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::BindRepeating(&HandleRequestCallback,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
WelcomeUI::~WelcomeUI() {}
|
||||
|
||||
void WelcomeUI::CreateBackgroundFetcher(
|
||||
size_t background_index,
|
||||
content::WebUIDataSource::GotDataCallback callback) {
|
||||
background_fetcher_ = std::make_unique<welcome::NtpBackgroundFetcher>(
|
||||
background_index, std::move(callback));
|
||||
}
|
||||
|
||||
void WelcomeUI::StorePageSeen(Profile* profile) {
|
||||
// Store that this profile has been shown the Welcome page.
|
||||
profile->GetPrefs()->SetBoolean(prefs::kHasSeenWelcomePage, true);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_
|
||||
#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/ui/webui/welcome/ntp_background_fetcher.h"
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
#include "content/public/browser/web_ui_controller.h"
|
||||
#include "content/public/browser/web_ui_data_source.h"
|
||||
#include "content/public/browser/webui_config.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
class WelcomeUI;
|
||||
|
||||
class WelcomeUIConfig : public content::DefaultWebUIConfig<WelcomeUI> {
|
||||
public:
|
||||
WelcomeUIConfig()
|
||||
: DefaultWebUIConfig(content::kChromeUIScheme,
|
||||
chrome::kChromeUIWelcomeHost) {}
|
||||
|
||||
// content::WebUIConfig:
|
||||
std::unique_ptr<content::WebUIController> CreateWebUIController(
|
||||
content::WebUI* web_ui,
|
||||
const GURL& url) override;
|
||||
bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
|
||||
};
|
||||
|
||||
// The WebUI for chrome://welcome, the page which greets new Desktop users and
|
||||
// promotes sign-in. By default, this page uses the "Welcome to Chrome" language
|
||||
// and layout; the "Take Chrome Everywhere" variant may be accessed by appending
|
||||
// the query string "?variant=everywhere".
|
||||
class WelcomeUI : public content::WebUIController {
|
||||
public:
|
||||
WelcomeUI(content::WebUI* web_ui, const GURL& url);
|
||||
|
||||
WelcomeUI(const WelcomeUI&) = delete;
|
||||
WelcomeUI& operator=(const WelcomeUI&) = delete;
|
||||
|
||||
~WelcomeUI() override;
|
||||
|
||||
void CreateBackgroundFetcher(
|
||||
size_t background_index,
|
||||
content::WebUIDataSource::GotDataCallback callback);
|
||||
|
||||
protected:
|
||||
// Visible for testing.
|
||||
static bool IsGzipped(const std::string& path);
|
||||
|
||||
private:
|
||||
void StorePageSeen(Profile* profile);
|
||||
std::unique_ptr<welcome::NtpBackgroundFetcher> background_fetcher_;
|
||||
base::WeakPtrFactory<WelcomeUI> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_
|
@ -425,12 +425,10 @@ template("chrome_extra_paks") {
|
||||
sources += [
|
||||
"$root_gen_dir/chrome/intro_resources.pak",
|
||||
"$root_gen_dir/chrome/profile_picker_resources.pak",
|
||||
"$root_gen_dir/chrome/welcome_resources.pak",
|
||||
]
|
||||
deps += [
|
||||
"//chrome/browser/resources/intro:resources",
|
||||
"//chrome/browser/resources/signin/profile_picker:resources",
|
||||
"//chrome/browser/resources/welcome:resources",
|
||||
]
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user