| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview |
| * 'settings-cookies-page' is the settings page containing cookies |
| * settings. |
| */ |
| |
| import '/shared/settings/prefs/prefs.js'; |
| import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; |
| import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; |
| import 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; |
| import '../controls/collapse_radio_button.js'; |
| import '../controls/settings_radio_group.js'; |
| import '../controls/settings_toggle_button.js'; |
| import '../icons.html.js'; |
| import '../privacy_icons.html.js'; |
| import '../settings_page/settings_subpage.js'; |
| import '../settings_shared.css.js'; |
| import '../site_settings/site_list.js'; |
| import './do_not_track_toggle.js'; |
| |
| import {PrefsMixin} from '/shared/settings/prefs/prefs_mixin.js'; |
| import type {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; |
| import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; |
| import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; |
| import {assert} from 'chrome://resources/js/assert.js'; |
| import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
| |
| import type {SettingsRadioGroupElement} from '../controls/settings_radio_group.js'; |
| import type {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; |
| import {loadTimeData} from '../i18n_setup.js'; |
| import type {MetricsBrowserProxy} from '../metrics_browser_proxy.js'; |
| import {MetricsBrowserProxyImpl, PrivacyElementInteractions} from '../metrics_browser_proxy.js'; |
| import {routes} from '../route.js'; |
| import type {Route} from '../router.js'; |
| import {RouteObserverMixin, Router} from '../router.js'; |
| import {SettingsViewMixin} from '../settings_page/settings_view_mixin.js'; |
| import {ContentSetting, ContentSettingsTypes, CookieControlsMode} from '../site_settings/constants.js'; |
| import {ThirdPartyCookieBlockingSetting} from '../site_settings/site_settings_browser_proxy.js'; |
| |
| import {getTemplate} from './cookies_page.html.js'; |
| |
| export interface SettingsCookiesPageElement { |
| $: { |
| toast: CrToastElement, |
| }; |
| } |
| |
| const SettingsCookiesPageElementBase = RouteObserverMixin(SettingsViewMixin( |
| WebUiListenerMixin(I18nMixin(PrefsMixin(PolymerElement))))); |
| |
| export class SettingsCookiesPageElement extends SettingsCookiesPageElementBase { |
| static get is() { |
| return 'settings-cookies-page'; |
| } |
| |
| static get template() { |
| return getTemplate(); |
| } |
| |
| static get properties() { |
| return { |
| /** |
| * Current search term. |
| */ |
| searchTerm: { |
| type: String, |
| notify: true, |
| value: '', |
| }, |
| |
| /** Cookie control modes for use in bindings. */ |
| cookieControlsModeEnum_: { |
| type: Object, |
| value: CookieControlsMode, |
| }, |
| |
| thirdPartyCookieBlockingSettingEnum_: { |
| type: Object, |
| value: ThirdPartyCookieBlockingSetting, |
| }, |
| |
| contentSettingEnum_: { |
| type: Object, |
| value: ContentSetting, |
| }, |
| |
| cookiesContentSettingType_: { |
| type: String, |
| value: ContentSettingsTypes.COOKIES, |
| }, |
| |
| blockAllPref_: { |
| type: Object, |
| value() { |
| return {}; |
| }, |
| }, |
| |
| is3pcdRedesignEnabled_: { |
| type: Boolean, |
| value: () => |
| loadTimeData.getBoolean('is3pcdCookieSettingsRedesignEnabled'), |
| }, |
| }; |
| } |
| |
| declare searchTerm: string; |
| declare private cookiesContentSettingType_: ContentSettingsTypes; |
| declare private blockAllPref_: chrome.settingsPrivate.PrefObject; |
| declare private is3pcdRedesignEnabled_: boolean; |
| |
| private metricsBrowserProxy_: MetricsBrowserProxy = |
| MetricsBrowserProxyImpl.getInstance(); |
| |
| override currentRouteChanged(newRoute: Route, oldRoute?: Route) { |
| super.currentRouteChanged(newRoute, oldRoute); |
| |
| if (newRoute !== routes.COOKIES) { |
| this.$.toast.hide(); |
| } |
| } |
| |
| private onSiteDataClick_() { |
| Router.getInstance().navigateTo(routes.SITE_SETTINGS_ALL); |
| } |
| |
| private onBlockAll3pcToggleChanged_(event: Event) { |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.BLOCK_ALL_THIRD_PARTY_COOKIES); |
| const target = event.target as SettingsToggleButtonElement; |
| if (target.checked) { |
| this.metricsBrowserProxy_.recordAction( |
| 'Settings.PrivacySandbox.Block3PCookies'); |
| } |
| } |
| |
| private showOrHideToast(switchedToBlock3pcs: boolean) { |
| // If this change resulted in the user now blocking 3P cookies where they |
| // previously were not, and any of privacy sandbox APIs are enabled, |
| // the privacy sandbox toast should be shown. |
| const areAnyPrivacySandboxApisEnabled = |
| this.getPref('privacy_sandbox.m1.topics_enabled').value || |
| this.getPref('privacy_sandbox.m1.fledge_enabled').value || |
| this.getPref('privacy_sandbox.m1.ad_measurement_enabled').value; |
| |
| if (areAnyPrivacySandboxApisEnabled && switchedToBlock3pcs) { |
| if (!loadTimeData.getBoolean('isPrivacySandboxRestricted')) { |
| this.$.toast.show(); |
| } |
| this.metricsBrowserProxy_.recordAction( |
| 'Settings.PrivacySandbox.Block3PCookies'); |
| } else { |
| this.$.toast.hide(); |
| } |
| } |
| |
| private onCookieControlsModeChanged_() { |
| // TODO(crbug.com/40244046): Use this.$.primarySettingGroup after the feature |
| // is launched and element isn't in dom-if anymore. |
| const primarySettingGroup: SettingsRadioGroupElement = |
| this.shadowRoot!.querySelector('#primarySettingGroup')!; |
| const selection = Number(primarySettingGroup.selected); |
| if (selection === CookieControlsMode.OFF) { |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.THIRD_PARTY_COOKIES_ALLOW); |
| } else if (selection === CookieControlsMode.INCOGNITO_ONLY) { |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.THIRD_PARTY_COOKIES_BLOCK_IN_INCOGNITO); |
| } else { |
| assert(selection === CookieControlsMode.BLOCK_THIRD_PARTY); |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.THIRD_PARTY_COOKIES_BLOCK); |
| } |
| |
| const currentCookieControlsMode = |
| this.getPref('profile.cookie_controls_mode').value; |
| this.showOrHideToast( |
| (currentCookieControlsMode === CookieControlsMode.OFF || |
| currentCookieControlsMode === CookieControlsMode.INCOGNITO_ONLY) && |
| selection === CookieControlsMode.BLOCK_THIRD_PARTY); |
| |
| primarySettingGroup.sendPrefChange(); |
| } |
| |
| private onThirdPartyCookieBlockingSettingChanged_() { |
| const thirdPartyCookieBlockingSettingGroup: SettingsRadioGroupElement = |
| this.shadowRoot!.querySelector('#thirdPartyCookieBlockingSettingGroup')! |
| ; |
| const selection = Number(thirdPartyCookieBlockingSettingGroup.selected); |
| if (selection === ThirdPartyCookieBlockingSetting.INCOGNITO_ONLY) { |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.THIRD_PARTY_COOKIES_BLOCK_IN_INCOGNITO); |
| this.metricsBrowserProxy_.recordAction( |
| 'Settings.ThirdPartyCookies.Allow'); |
| } else { |
| assert(selection === ThirdPartyCookieBlockingSetting.BLOCK_THIRD_PARTY); |
| this.metricsBrowserProxy_.recordSettingsPageHistogram( |
| PrivacyElementInteractions.THIRD_PARTY_COOKIES_BLOCK); |
| this.metricsBrowserProxy_.recordAction( |
| 'Settings.ThirdPartyCookies.Block'); |
| } |
| |
| const currentThirdPartyCookieBlockingSetting = |
| this.getPref('generated.third_party_cookie_blocking_setting').value; |
| this.showOrHideToast( |
| currentThirdPartyCookieBlockingSetting === |
| ThirdPartyCookieBlockingSetting.INCOGNITO_ONLY && |
| selection === ThirdPartyCookieBlockingSetting.BLOCK_THIRD_PARTY); |
| |
| thirdPartyCookieBlockingSettingGroup.sendPrefChange(); |
| } |
| |
| private onPrivacySandboxClick_() { |
| this.metricsBrowserProxy_.recordAction( |
| 'Settings.PrivacySandbox.OpenedFromCookiesPageToast'); |
| this.$.toast.hide(); |
| // TODO(crbug.com/40162029): Replace this with an ordinary OpenWindowProxy |
| // call. |
| this.shadowRoot!.querySelector<HTMLAnchorElement>( |
| '#privacySandboxLink')!.click(); |
| } |
| |
| private relatedWebsiteSetsToggleDisabled_() { |
| return this.getPref('profile.cookie_controls_mode').value !== |
| CookieControlsMode.BLOCK_THIRD_PARTY; |
| } |
| |
| private relatedWebsiteSetsToggle3pcSettingDisabled_() { |
| return this.getPref('generated.third_party_cookie_blocking_setting') |
| .value !== ThirdPartyCookieBlockingSetting.BLOCK_THIRD_PARTY; |
| } |
| |
| // SettingsViewMixin implementation. |
| override getFocusConfig() { |
| return new Map([ |
| [ |
| `${routes.SITE_SETTINGS_ALL.path}_${routes.COOKIES.path}`, |
| '#siteDataTrigger', |
| ], |
| ]); |
| } |
| |
| // SettingsViewMixin implementation. |
| override focusBackButton() { |
| this.shadowRoot!.querySelector('settings-subpage')!.focusBackButton(); |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'settings-cookies-page': SettingsCookiesPageElement; |
| } |
| } |
| |
| customElements.define( |
| SettingsCookiesPageElement.is, SettingsCookiesPageElement); |