Commit 96aea1c4 authored by Monica Basta's avatar Monica Basta Committed by Commit Bot

[ProfilePicker]: Add 3 dotted menu and remove profile option.

This CL adds the 3 dotted menu shown per profile. The menu currently
supports deleting a profile and the remove confirmation action menu
shown afterwards. The remove confirmation has a warning message, profile
statistics and remove confirmation button.

Screenshot:
https://drive.google.com/file/d/1jjYRgjXEcNArNvLdEkRDa3XMV-r87DTY/view?usp=sharing
https://drive.google.com/file/d/1k20VUvBPysAVZrqbcXVtPgHsV6uAQZIm/view?usp=sharing
https://drive.google.com/file/d/18spWU68LxO6KzuPc-PZi7NHeRv62I25c/view?usp=sharing

Bug: 1063856
Change-Id: I06714382cd85d2142caae717ae526e7ee08e8e8b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2329890
Commit-Queue: Monica Basta <msalama@chromium.org>
Reviewed-by: default avatarEsmael Elmoslimany <aee@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795216}
parent 286a19d6
......@@ -1153,6 +1153,9 @@ Chromium is unable to recover your settings.
<message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle">
Use Chromium Spaces to keep your browsing organized on this device
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu">
This space’s browsing data will be deleted from this device. To recover the data, sign in to Chromium as
</message>
<message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE" desc="Profile picker profile type choice
title">
Set up your new Chromium Space
......
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
......@@ -1169,6 +1169,9 @@ Google Chrome is unable to recover your settings.
<message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle">
Use Chrome Spaces to keep your browsing organized on this device
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu">
This space’s browsing data will be deleted from this device. To recover the data, sign in to Chrome as
</message>
<message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE" desc="Profile picker profile type choice
title">
Set up your new Chrome Space
......
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
......@@ -673,6 +673,30 @@
<message name="IDS_PROFILE_PICKER_BACK_BUTTON_LABEL" desc="Label for a button that navigates user to the previous page">
Back
</message>
<message name="IDS_PROFILE_PICKER_PROFILE_MENU_BUTTON_NAME" desc="Text to be spoken when the focus is set to the menu button of the profile card on the picker main screen or shown on hover.">
Options menu for <ph name="PROFILE_LOCAL_NAME">$1<ex>Personal</ex></ph>
</message>
<message name="IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT" desc="Text of the remove button in profile card menu and on the title of the remove warning.">
Remove
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE" desc="Main text shown as a warning when attempting to remove an user.">
This will permanently delete your browsing data from this device.
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_HISTORY" desc="The title of a statistic (browsing history) shown inside a table below the warning text when attempting to remove an user. A number is displayed next to it.">
Browsing history
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_PASSWORDS" desc="The title of a statistic (passwords) shown inside a table below the warning text when attempting to remove a profile. A number is displayed next to it.">
Passwords
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_BOOKMARKS" desc="The title of a statistic (bookmarks) shown inside a table below the warning text when attempting to remove a profile. A number is displayed next to it.">
Bookmarks
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_AUTOFILL" desc="The title of a statistic (autofill) shown inside a table below the warning text when attempting to remove a profile. A number is displayed next to it.">
Autofill form data
</message>
<message name="IDS_PROFILE_PICKER_REMOVE_WARNING_CALCULATING" desc="This is shown next to the loading statistics in the remove action menu. All occurrences of '...' will be eventually replaced by numbers when the statistics are loaded.">
...
</message>
<message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_SUBTITLE" desc="Profile picker profile type choice
subtitle">
Sign in to Sync your bookmarks, passwords, history and more on all your devices
......
10bff9f18c6ba460847f7ba4c3d7744784459e46
\ No newline at end of file
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
9b7ea173a8fb0ffe3fb351fd117b3846fce1e058
\ No newline at end of file
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
e9dd45d35c36c4f38d438ee50b7246feb4c7ce71
\ No newline at end of file
142eeb0b333995bb9e97f4e8deacb899fd9a3781
\ No newline at end of file
......@@ -29,6 +29,7 @@ js_library("profile_picker_main_view") {
deps = [
":manage_profiles_browser_proxy",
":navigation_behavior",
":profile_card",
"//third_party/polymer/v3_0/components-chromium/iron-icon",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m",
......@@ -54,6 +55,28 @@ js_library("profile_picker_app") {
]
}
js_library("profile_card") {
deps = [
":manage_profiles_browser_proxy",
":profile_card_menu",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_elements/cr_button:cr_button.m",
]
}
js_library("profile_card_menu") {
deps = [
":manage_profiles_browser_proxy",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m",
"//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:i18n_behavior.m",
"//ui/webui/resources/js:load_time_data.m",
"//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
js_library("manage_profiles_browser_proxy") {
deps = [ "//ui/webui/resources/js:cr.m" ]
externs_list = [ "$externs_path/chrome_send.js" ]
......@@ -71,6 +94,7 @@ html_to_js("web_components_local") {
"profile_picker_app.js",
"profile_picker_main_view.js",
"profile_card.js",
"profile_card_menu.js",
"profile_picker_shared_css.js",
]
}
......@@ -9,7 +9,9 @@ import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js
* @typedef {{
* profilePath: string,
* localProfileName: string,
* isSignedIn: Boolean,
* gaiaName: string,
* userName: string,
* avatarIcon: string,
* }}
*/
......@@ -54,6 +56,12 @@ export class ManageProfilesBrowserProxy {
*/
getNewProfileSuggestedThemeInfo() {}
/**
* Retrieves profile statistics to be shown in the remove profile warning.
* @param {string} profilePath
*/
getProfileStatistics(profilePath) {}
/** Loads Google sign in page.*/
loadSignInProfileCreationFlow() {}
}
......@@ -85,6 +93,11 @@ export class ManageProfilesBrowserProxyImpl {
return sendWithPromise('getNewProfileSuggestedThemeInfo');
}
/** @override */
getProfileStatistics(profilePath) {
chrome.send('getProfileStatistics', [profilePath]);
}
/** @override */
loadSignInProfileCreationFlow() {
chrome.send('loadSignInProfileCreationFlow');
......
......@@ -33,6 +33,7 @@
</style>
<cr-button on-click="onProfileClick_">
<profile-card-menu profile-state="[[profileState]]"></profile-card-menu>
<!-- TODO(msalama): Implement editing local profile name in place -->
<div class="profile-info">[[profileState.localProfileName]]</div>
<img class="profile-avatar" alt="" src="[[profileState.avatarIcon]]">
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
import './profile_card_menu.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js';
......@@ -16,7 +17,7 @@ Polymer({
/** @type {!ProfileState} */
profileState: {
type: Object,
}
},
},
/** @private {ManageProfilesBrowserProxy} */
......@@ -33,5 +34,4 @@ Polymer({
this.manageProfilesBrowserProxy_.launchSelectedProfile(
this.profileState.profilePath);
},
});
<style include="cr-icons profile-picker-shared">
#moreActionsButton {
--cr-icon-button-icon-size: 14px;
--cr-icon-button-margin-end: 0;
--cr-icon-button-margin-start: 0;
--cr-icon-button-size: 24px;
position: absolute;
right: 4px;
top: 4px;
}
cr-action-menu {
font-weight: normal;
}
#removeActionMenu {
pointer-events: none;
}
#removeConfirmation {
margin-top: 16px;
pointer-events: none;
width: 234px;
}
#removeConfirmation > * {
margin: 0 16px 16px 16px;
}
.header {
font-size: 1.17em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.key-text {
font-weight: 500;
}
.statistics {
border: 1px solid var(--google-grey-refresh-100);
border-radius: 4px;
box-sizing: border-box;
padding: 12px 16px 16px 12px;
width: -webkit-fill-available;
}
.category {
text-align: start;
}
.count {
color: var(--google-grey-refresh-500);
text-align: end;
}
#removeConfirmationButton {
--active-shadow-action-rgb: var(--google-red-500-rgb);
--bg-action: var(--google-red-700);
--hover-bg-action: rgba(var(--google-red-700-rgb), .9);
--hover-shadow-action-rgb: var(--google-red-500-rgb);
background-color: var(--google-red-700);
border-radius: 4px;
color: var(--ink-color-action);
font-weight: 500;
left: 50%;
margin-bottom: 16px;
pointer-events: auto;
transform: translateX(-50%);
width: 111px;
}
#removeConfirmationButton:hover {
background-color: var(--hover-bg-action);
}
</style>
<cr-icon-button class="icon-more-vert" id="moreActionsButton"
on-click="onMoreActionsButtonClicked_" title$="[[profileMenuText_]]"
aria-label$="[[profileMenuText_]]">
</cr-icon-button>
<cr-action-menu id="actionMenu" role-description="menu">
<button class="dropdown-item" on-click="onRemoveButtonClicked_">
$i18n{profileMenuRemoveText}
</button>
</cr-action-menu>
<cr-action-menu id="removeActionMenu" role-description="menu">
<div id="removeConfirmation">
<div class="header">
$i18n{profileMenuRemoveText}
<span class="key-text">[[profileState.localProfileName]]</span>
</div>
<div>
[[removeWarningText_]]
<span class="key-text">[[profileState.userName]]</span>
</div>
<table class="statistics">
<template is="dom-repeat" items="[[profileStatistics_]]">
<tr>
<td class="category">[[getProfileStatisticText_(item)]]</td>
<td class="count">
[[getProfileStatisticCount_(item, statistics_)]]</td>
<tr>
</template>
</table>
</div>
<cr-button id="removeConfirmationButton"class="dropdown-item action-button"
on-click="onRemoveComfirationClicked_">
$i18n{profileMenuRemoveText}
</cr-button>
</cr-action-menu>
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js';
import 'chrome://resources/cr_elements/cr_icons_css.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import './profile_picker_shared_css.js';
import {assertNotReached} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import './strings.js';
import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js';
/**
* @typedef {{
* BrowsingHistory: number,
* Passwords: number,
* Bookmarks: number,
* Autofill: number,
* }}
*/
let Statistics;
/**
* This is the data structure sent back and forth between C++ and JS.
* @typedef {{
* profilePath: string,
* statistics: Statistics,
* }}
*/
let StatisticsResult;
/**
* Profile statistics data types.
* @enum {string}
*/
const ProfileStatistics = {
BROWSING_HISTORY: 'BrowsingHistory',
PASSWORDS: 'Passwords',
BOOKMARKS: 'Bookmarks',
AUTOFILL: 'Autofill',
};
Polymer({
is: 'profile-card-menu',
_template: html`{__html_template__}`,
behaviors: [I18nBehavior, WebUIListenerBehavior],
properties: {
/** @type {!ProfileState} */
profileState: {
type: Object,
},
/**
* Results of profile statistics, keyed by the suffix of the corresponding
* data type, as reported by the C++ side.
* @private {!Object<number>}
*/
statistics_: {
type: Object,
// Will be filled as results are reported.
value() {
return {};
}
},
/**
* List of selected data types.
* @private {!Array<string>}
*/
profileStatistics_: {
type: Object,
value: [
ProfileStatistics.BROWSING_HISTORY, ProfileStatistics.PASSWORDS,
ProfileStatistics.BOOKMARKS, ProfileStatistics.AUTOFILL
],
},
profileMenuText_: {
type: String,
computed: 'computeProfileMenuText_(profileState)',
},
removeWarningText_: {
type: String,
computed: 'computeRemoveWarningText_(profileState)',
},
},
/** @private {ManageProfilesBrowserProxy} */
manageProfilesBrowserProxy_: null,
/** @override */
ready() {
this.manageProfilesBrowserProxy_ =
ManageProfilesBrowserProxyImpl.getInstance();
},
/** @override */
attached() {
this.addWebUIListener(
'profile-statistics-received',
this.handleProfileStatsReceived_.bind(this));
},
/**
* @return {string}
* @private
*/
computeProfileMenuText_() {
return this.i18n('profileMenuName', this.profileState.localProfileName);
},
/**
* @return {string}
* @private
*/
computeRemoveWarningText_() {
if (this.profileState.isSignedIn) {
return this.i18n('removeWarningSignedInProfile');
}
return this.i18n('removeWarningLocalProfile');
},
/**
* @param {!Event} e
* @private
*/
onMoreActionsButtonClicked_(e) {
e.stopPropagation();
e.preventDefault();
this.$.actionMenu.showAt(this.$.moreActionsButton);
},
/**
* @param {!Event} e
* @private
*/
onRemoveButtonClicked_(e) {
e.stopPropagation();
e.preventDefault();
this.dataCounters_ = {};
this.manageProfilesBrowserProxy_.getProfileStatistics(
this.profileState.profilePath);
this.$.actionMenu.close();
this.$.removeActionMenu.showAt(this.$.moreActionsButton);
},
/**
* @param {!StatisticsResult} result
* @private
*/
handleProfileStatsReceived_(result) {
if (result.profilePath !== this.profileState.profilePath) {
return;
}
this.statistics_ = result.statistics;
},
/**
* @param {string} dataType
* @return {string}
* @private
*/
getProfileStatisticText_(dataType) {
switch (dataType) {
case ProfileStatistics.BROWSING_HISTORY:
return this.i18n('removeWarningHistory');
case ProfileStatistics.PASSWORDS:
return this.i18n('removeWarningPasswords');
case ProfileStatistics.BOOKMARKS:
return this.i18n('removeWarningBookmarks');
case ProfileStatistics.AUTOFILL:
return this.i18n('removeWarningAutofill');
default:
assertNotReached();
}
},
/**
* @param {string} dataType
* @return {string}
* @private
*/
getProfileStatisticCount_(dataType) {
const count = this.statistics_[dataType];
return (count === undefined) ? this.i18n('removeWarningCalculating') :
count.toString();
},
/**
* @param {!Event} e
* @private
*/
onRemoveComfirationClicked_(e) {
e.stopPropagation();
e.preventDefault();
// TODO(crbug.com/1063856): Add implementation.
},
});
......@@ -33,7 +33,10 @@
use_base_dir="false" type="BINDATA"/>
<include name="IDR_PROFILE_PICKER_PROFILE_CARD_JS"
file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_card.js"
use_base_dir="false" type="BINDATA" preprocess="true"/>
use_base_dir="false" type="BINDATA"/>
<include name="IDR_PROFILE_PICKER_PROFILE_CARD_MENU_JS"
file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_card_menu.js"
use_base_dir="false" type="BINDATA"/>
<include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_JS"
file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js"
use_base_dir="false" type="BINDATA"/>
......
<template>
<style>
html {
font-family: roboto;
}
h2 {
font-size: 1.85em;
font-weight: normal;
}
h3 {
color: var(--google-grey-refresh-700);
font-weight: normal;
......
......@@ -13,7 +13,10 @@
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_statistics.h"
#include "chrome/browser/profiles/profile_statistics_factory.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/profile_picker.h"
#include "chrome/common/pref_names.h"
......@@ -55,6 +58,10 @@ void ProfilePickerHandler::RegisterMessages() {
base::BindRepeating(
&ProfilePickerHandler::HandleGetNewProfileSuggestedThemeInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getProfileStatistics",
base::BindRepeating(&ProfilePickerHandler::HandleGetProfileStatistics,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"loadSignInProfileCreationFlow",
base::BindRepeating(
......@@ -149,6 +156,57 @@ void ProfilePickerHandler::HandleGetNewProfileSuggestedThemeInfo(
ResolveJavascriptCallback(callback_id, std::move(dict));
}
void ProfilePickerHandler::HandleGetProfileStatistics(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(1U, args->GetSize());
const base::Value& profile_path_value = args->GetList()[0];
base::Optional<base::FilePath> profile_path =
util::ValueToFilePath(profile_path_value);
if (!profile_path)
return;
Profile* profile =
g_browser_process->profile_manager()->GetProfileByPath(*profile_path);
if (profile) {
GatherProfileStatistics(profile);
} else {
g_browser_process->profile_manager()->LoadProfileByPath(
*profile_path, false,
base::BindOnce(&ProfilePickerHandler::GatherProfileStatistics,
weak_factory_.GetWeakPtr()));
}
}
void ProfilePickerHandler::GatherProfileStatistics(Profile* profile) {
if (!profile) {
return;
}
ProfileStatisticsFactory::GetForProfile(profile)->GatherStatistics(
base::BindRepeating(&ProfilePickerHandler::OnProfileStatisticsReceived,
weak_factory_.GetWeakPtr(), profile->GetPath()));
}
void ProfilePickerHandler::OnProfileStatisticsReceived(
base::FilePath profile_path,
profiles::ProfileCategoryStats result) {
if (!IsJavascriptAllowed())
return;
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetKey("profilePath", util::FilePathToValue(profile_path));
base::Value stats(base::Value::Type::DICTIONARY);
// Categories are defined in |kProfileStatisticsCategories|
// {"BrowsingHistory", "Passwords", "Bookmarks", "Autofill"}.
for (const auto& item : result) {
stats.SetIntKey(item.category, item.count);
}
dict.SetKey("statistics", std::move(stats));
FireWebUIListener("profile-statistics-received", std::move(dict));
}
void ProfilePickerHandler::HandleLoadSignInProfileCreationFlow(
const base::ListValue* args) {
// TODO(crbug.com/1063856): Add implementation.
......@@ -179,8 +237,12 @@ base::Value ProfilePickerHandler::GetProfilesList() {
profile_entry->SetKey("profilePath",
util::FilePathToValue(entry->GetPath()));
profile_entry->SetString("localProfileName", entry->GetLocalProfileName());
// GAIA name can be empty, if the profile is not signed in to chrome.
profile_entry->SetBoolPath(
"isSignedIn", entry->GetSigninState() != SigninState::kNotSignedIn);
// GAIA name/user name can be empty, if the profile is not signed in to
// chrome.
profile_entry->SetString("gaiaName", entry->GetGAIANameToDisplay());
profile_entry->SetString("userName", entry->GetUserName());
gfx::Image icon = profiles::GetSizedAvatarIcon(
entry->GetAvatarIcon(), true, kAvatarIconSize, kAvatarIconSize);
std::string icon_url = webui::GetBitmapDataUrl(icon.AsBitmap());
......
......@@ -9,6 +9,7 @@
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_statistics_common.h"
#include "content/public/browser/web_ui_message_handler.h"
// The handler for Javascript messages related to the profile picker main view.
......@@ -29,8 +30,12 @@ class ProfilePickerHandler : public content::WebUIMessageHandler,
void HandleLaunchGuestProfile(const base::ListValue* args);
void HandleAskOnStartupChanged(const base::ListValue* args);
void HandleGetNewProfileSuggestedThemeInfo(const base::ListValue* args);
void HandleGetProfileStatistics(const base::ListValue* args);
void HandleLoadSignInProfileCreationFlow(const base::ListValue* args);
void GatherProfileStatistics(Profile* profile);
void OnProfileStatisticsReceived(base::FilePath profile_path,
profiles::ProfileCategoryStats result);
void OnSwitchToProfileComplete(Profile* profile,
Profile::CreateStatus profile_create_status);
void PushProfilesList();
......
......@@ -27,6 +27,18 @@ void AddStrings(content::WebUIDataSource* html_source) {
{"askOnStartupCheckboxText", IDS_PROFILE_PICKER_ASK_ON_STARTUP},
{"browseAsGuestButton", IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON},
{"backButtonLabel", IDS_PROFILE_PICKER_BACK_BUTTON_LABEL},
{"profileMenuName", IDS_PROFILE_PICKER_PROFILE_MENU_BUTTON_NAME},
{"profileMenuRemoveText", IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT},
{"removeWarningLocalProfile",
IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE},
{"removeWarningSignedInProfile",
IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE},
{"removeWarningHistory", IDS_PROFILE_PICKER_REMOVE_WARNING_HISTORY},
{"removeWarningPasswords", IDS_PROFILE_PICKER_REMOVE_WARNING_PASSWORDS},
{"removeWarningBookmarks", IDS_PROFILE_PICKER_REMOVE_WARNING_BOOKMARKS},
{"removeWarningAutofill", IDS_PROFILE_PICKER_REMOVE_WARNING_AUTOFILL},
{"removeWarningCalculating",
IDS_PROFILE_PICKER_REMOVE_WARNING_CALCULATING},
{"profileTypeChoiceTitle",
IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE},
{"profileTypeChoiceSubtitle",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment