| // 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 |
| * 'personalization-options' contains several toggles related to |
| * personalizations. |
| */ |
| import '//resources/cr_elements/cr_button/cr_button.js'; |
| import '//resources/cr_elements/cr_toggle/cr_toggle.js'; |
| import '/shared/settings/prefs/prefs.js'; |
| import '../controls/settings_toggle_button.js'; |
| import '../people_page/signout_dialog.js'; |
| import 'chrome://resources/cr_elements/md_select.css.js'; |
| // <if expr="not is_chromeos"> |
| import '../relaunch_confirmation_dialog.js'; |
| // </if> |
| import '../settings_shared.css.js'; |
| // <if expr="not is_chromeos"> |
| import '//resources/cr_elements/cr_toast/cr_toast.js'; |
| import 'chrome://resources/cr_elements/cr_shared_style.css.js'; |
| |
| // </if> |
| |
| import type {CrLinkRowElement} from '//resources/cr_elements/cr_link_row/cr_link_row.js'; |
| import type {CrToastElement} from '//resources/cr_elements/cr_toast/cr_toast.js'; |
| import {WebUiListenerMixin} from '//resources/cr_elements/web_ui_listener_mixin.js'; |
| import {assert} from '//resources/js/assert.js'; |
| import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
| import type {ChromeSigninUserChoiceInfo, SyncBrowserProxy, SyncStatus} from '/shared/settings/people_page/sync_browser_proxy.js'; |
| import {ChromeSigninUserChoice, SignedInState, SyncBrowserProxyImpl} from '/shared/settings/people_page/sync_browser_proxy.js'; |
| import {PrefsMixin} from '/shared/settings/prefs/prefs_mixin.js'; |
| import type {MetricsReporting, PrivacyPageBrowserProxy} from '/shared/settings/privacy_page/privacy_page_browser_proxy.js'; |
| import {PrivacyPageBrowserProxyImpl} from '/shared/settings/privacy_page/privacy_page_browser_proxy.js'; |
| import {HelpBubbleMixin} from 'chrome://resources/cr_components/help_bubble/help_bubble_mixin.js'; |
| import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; |
| |
| import type {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; |
| import {loadTimeData} from '../i18n_setup.js'; |
| import {pageVisibility} from '../page_visibility.js'; |
| import type {PrivacyPageVisibility} from '../page_visibility.js'; |
| import type {SettingsSignoutDialogElement} from '../people_page/signout_dialog.js'; |
| import {RelaunchMixin, RestartType} from '../relaunch_mixin.js'; |
| |
| import {getTemplate} from './personalization_options.html.js'; |
| |
| export interface SettingsPersonalizationOptionsElement { |
| $: { |
| toast: CrToastElement, |
| signinAllowedToggle: SettingsToggleButtonElement, |
| metricsReportingControl: SettingsToggleButtonElement, |
| metricsReportingLink: CrLinkRowElement, |
| urlCollectionToggle: SettingsToggleButtonElement, |
| chromeSigninUserChoiceSelection: HTMLSelectElement, |
| chromeSigninUserChoiceToast: CrToastElement, |
| }; |
| } |
| |
| const SettingsPersonalizationOptionsElementBase = HelpBubbleMixin( |
| RelaunchMixin(WebUiListenerMixin(I18nMixin(PrefsMixin(PolymerElement))))); |
| |
| // browser_element_identifiers constants |
| const ANONYMIZED_URL_COLLECTION_ID = |
| 'kAnonymizedUrlCollectionPersonalizationSettingId'; |
| |
| export class SettingsPersonalizationOptionsElement extends |
| SettingsPersonalizationOptionsElementBase { |
| static get is() { |
| return 'settings-personalization-options'; |
| } |
| |
| static get template() { |
| return getTemplate(); |
| } |
| |
| static get properties() { |
| return { |
| syncStatus: Object, |
| |
| // <if expr="_google_chrome and not is_chromeos"> |
| // TODO(dbeam): make a virtual.* pref namespace and set/get this normally |
| // (but handled differently in C++). |
| metricsReportingPref_: { |
| type: Object, |
| value() { |
| // TODO(dbeam): this is basically only to appease PrefControlMixin. |
| // Maybe add a no-validate attribute instead? This makes little sense. |
| return {}; |
| }, |
| }, |
| |
| showRestart_: Boolean, |
| // </if> |
| |
| showSearchAggregatorSuggest_: { |
| type: Boolean, |
| value: () => loadTimeData.getBoolean('showSearchAggregatorSuggest'), |
| }, |
| |
| searchAggregatorSuggestFakePref_: { |
| type: Object, |
| value() { |
| return { |
| key: 'enterprise_search_aggregator_settings.fake_pref', |
| type: chrome.settingsPrivate.PrefType.BOOLEAN, |
| value: true, |
| enforcement: chrome.settingsPrivate.Enforcement.ENFORCED, |
| controlledBy: chrome.settingsPrivate.ControlledBy.USER_POLICY, |
| }; |
| }, |
| }, |
| |
| showSignoutDialog_: Boolean, |
| |
| syncFirstSetupInProgress_: { |
| type: Boolean, |
| value: false, |
| computed: 'computeSyncFirstSetupInProgress_(syncStatus)', |
| }, |
| |
| // <if expr="not is_chromeos"> |
| signinAvailable_: { |
| type: Boolean, |
| value: () => loadTimeData.getBoolean('signinAvailable'), |
| }, |
| |
| chromeSigninUserChoiceInfo_: { |
| type: Object, |
| value: null, |
| }, |
| |
| /** Expose ChromeSigninUserChoice enum to HTML bindings. */ |
| chromeSigninUserChoiceEnum_: { |
| type: Object, |
| value: ChromeSigninUserChoice, |
| }, |
| // </if> |
| }; |
| } |
| |
| declare syncStatus: SyncStatus; |
| |
| // <if expr="_google_chrome and not is_chromeos"> |
| declare private metricsReportingPref_: |
| chrome.settingsPrivate.PrefObject<boolean>; |
| declare private showRestart_: boolean; |
| // </if> |
| |
| declare private showSearchAggregatorSuggest_: boolean; |
| declare private searchAggregatorSuggestFakePref_: |
| chrome.settingsPrivate.PrefObject<boolean>; |
| |
| declare private showSignoutDialog_: boolean; |
| declare private syncFirstSetupInProgress_: boolean; |
| |
| // <if expr="not is_chromeos"> |
| declare private signinAvailable_: boolean; |
| |
| declare private chromeSigninUserChoiceInfo_: ChromeSigninUserChoiceInfo; |
| // </if> |
| |
| private browserProxy_: PrivacyPageBrowserProxy = |
| PrivacyPageBrowserProxyImpl.getInstance(); |
| |
| private syncBrowserProxy_: SyncBrowserProxy = |
| SyncBrowserProxyImpl.getInstance(); |
| |
| private computeSyncFirstSetupInProgress_(): boolean { |
| return !!this.syncStatus && !!this.syncStatus.firstSetupInProgress; |
| } |
| |
| private showPriceEmailNotificationsToggle_(): boolean { |
| if (!loadTimeData.getBoolean('changePriceEmailNotificationsEnabled') || |
| !this.syncStatus) { |
| return false; |
| } |
| // Only show the toggle when the user signed in. |
| if (loadTimeData.getBoolean('replaceSyncPromosWithSignInPromos') && |
| this.syncStatus.signedInState === SignedInState.SIGNED_IN) { |
| return true; |
| } |
| return this.syncStatus.signedInState === SignedInState.SYNCING; |
| } |
| |
| private getPriceEmailNotificationsPrefDesc_(): string { |
| const username = this.syncStatus.signedInUsername || ''; |
| return loadTimeData.getStringF('priceEmailNotificationsPrefDesc', username); |
| } |
| |
| override ready() { |
| super.ready(); |
| |
| // <if expr="_google_chrome and not is_chromeos"> |
| const setMetricsReportingPref = (metricsReporting: MetricsReporting) => |
| this.setMetricsReportingPref_(metricsReporting); |
| this.addWebUiListener('metrics-reporting-change', setMetricsReportingPref); |
| this.browserProxy_.getMetricsReporting().then(setMetricsReportingPref); |
| // </if> |
| |
| // <if expr="not is_chromeos"> |
| this.syncBrowserProxy_.getChromeSigninUserChoiceInfo().then( |
| this.setChromeSigninUserChoiceInfo_.bind(this)); |
| this.addWebUiListener( |
| 'chrome-signin-user-choice-info-change', |
| this.setChromeSigninUserChoiceInfo_.bind(this)); |
| // </if> |
| |
| this.registerHelpBubble( |
| ANONYMIZED_URL_COLLECTION_ID, |
| this.$.urlCollectionToggle.getBubbleAnchor(), {anchorPaddingTop: 10}); |
| } |
| |
| // <if expr="is_chromeos"> |
| /** |
| * @return the autocomplete search suggestions CrToggleElement. |
| */ |
| getSearchSuggestToggle(): SettingsToggleButtonElement|null { |
| return this.shadowRoot!.querySelector<SettingsToggleButtonElement>( |
| '#searchSuggestToggle'); |
| } |
| |
| /** |
| * @return the anonymized URL collection CrToggleElement. |
| */ |
| getUrlCollectionToggle(): SettingsToggleButtonElement|null { |
| return this.shadowRoot!.querySelector<SettingsToggleButtonElement>( |
| '#urlCollectionToggle'); |
| } |
| // </if> |
| |
| // <if expr="_google_chrome and not is_chromeos"> |
| private onMetricsReportingChange_() { |
| const enabled = this.$.metricsReportingControl.checked; |
| this.browserProxy_.setMetricsReportingEnabled(enabled); |
| } |
| |
| private setMetricsReportingPref_(metricsReporting: MetricsReporting) { |
| const hadPreviousPref = this.metricsReportingPref_.value !== undefined; |
| const pref: chrome.settingsPrivate.PrefObject<boolean> = { |
| key: '', |
| type: chrome.settingsPrivate.PrefType.BOOLEAN, |
| value: metricsReporting.enabled, |
| }; |
| if (metricsReporting.managed) { |
| pref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; |
| pref.controlledBy = chrome.settingsPrivate.ControlledBy.USER_POLICY; |
| } |
| |
| // Ignore the next change because it will happen when we set the pref. |
| this.metricsReportingPref_ = pref; |
| |
| // TODO(dbeam): remember whether metrics reporting was enabled when Chrome |
| // started. |
| if (metricsReporting.managed) { |
| this.showRestart_ = false; |
| } else if (hadPreviousPref) { |
| this.showRestart_ = true; |
| } |
| } |
| // </if> |
| |
| private showSearchSuggestToggle_(): boolean { |
| if (pageVisibility?.privacy === undefined) { |
| // pageVisibility isn't defined in non-Guest profiles (crbug.com/1288911). |
| return true; |
| } |
| return (pageVisibility.privacy as PrivacyPageVisibility).searchPrediction; |
| } |
| |
| // <if expr="is_chromeos"> |
| private navigateTo_(url: string): void { |
| window.location.href = url; |
| } |
| |
| private onMetricsReportingLinkClick_() { |
| // TODO(wesokuhara) Deep link directly to metrics toggle via settingId. |
| this.navigateTo_(loadTimeData.getString('osSettingsPrivacyHubSubpageUrl')); |
| } |
| // </if> |
| |
| // <if expr="_google_chrome"> |
| private onUseSpellingServiceToggle_(event: Event) { |
| // If turning on using the spelling service, automatically turn on |
| // spellcheck so that the spelling service can run. |
| if ((event.target as SettingsToggleButtonElement).checked) { |
| this.setPrefValue('browser.enable_spellchecking', true); |
| } |
| } |
| |
| // <if expr="not is_chromeos"> |
| private showSpellCheckControlToggle_(): boolean { |
| return ( |
| !!(this.prefs as {spellcheck?: any}).spellcheck && |
| this.getPref<string[]>('spellcheck.dictionaries').value.length > 0); |
| } |
| // </if><!-- not chromeos --> |
| |
| // <if expr="is_chromeos"> |
| private showSpellCheckControlLink_(): boolean { |
| return ( |
| !!(this.prefs as {spellcheck?: any}).spellcheck && |
| this.getPref<string[]>('spellcheck.dictionaries').value.length > 0); |
| } |
| |
| private onUseSpellingServiceLinkClick_() { |
| this.navigateTo_(loadTimeData.getString('osSyncSetupSettingsUrl')); |
| } |
| // </if><!-- chromeos --> |
| // </if><!-- _google_chrome --> |
| |
| private onSigninAllowedChange_() { |
| if (this.syncStatus.signedInState === SignedInState.SYNCING && |
| !this.$.signinAllowedToggle.checked) { |
| // Switch the toggle back on and show the signout dialog. |
| this.$.signinAllowedToggle.checked = true; |
| this.showSignoutDialog_ = true; |
| } else { |
| this.$.signinAllowedToggle.sendPrefChange(); |
| this.$.toast.show(); |
| } |
| } |
| |
| private onSignoutDialogClosed_() { |
| if (this.shadowRoot! |
| .querySelector<SettingsSignoutDialogElement>( |
| 'settings-signout-dialog')!.wasConfirmed()) { |
| this.$.signinAllowedToggle.checked = false; |
| this.$.signinAllowedToggle.sendPrefChange(); |
| this.$.toast.show(); |
| } |
| this.showSignoutDialog_ = false; |
| } |
| |
| private onRestartClick_(e: Event) { |
| e.stopPropagation(); |
| this.performRestart(RestartType.RESTART); |
| } |
| |
| // <if expr="not is_chromeos"> |
| private setChromeSigninUserChoiceInfo_(info: ChromeSigninUserChoiceInfo) { |
| this.chromeSigninUserChoiceInfo_ = info; |
| if (info.choice !== ChromeSigninUserChoice.NO_CHOICE) { |
| this.$.chromeSigninUserChoiceSelection.value = info.choice.toString(); |
| } |
| } |
| |
| private onChromeSigninChoiceSelectionChanged_() { |
| const selected = Number(this.$.chromeSigninUserChoiceSelection.value); |
| assert(selected !== ChromeSigninUserChoice.NO_CHOICE); |
| |
| this.$.chromeSigninUserChoiceToast.show(); |
| this.syncBrowserProxy_.setChromeSigninUserChoice( |
| selected, this.chromeSigninUserChoiceInfo_.signedInEmail); |
| } |
| // </if> |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'settings-personalization-options': SettingsPersonalizationOptionsElement; |
| } |
| } |
| |
| customElements.define( |
| SettingsPersonalizationOptionsElement.is, |
| SettingsPersonalizationOptionsElement); |