Bug 1795041 - Add a cookie banner handling per-site toggle to the protection panel. r=timhuang

Differential Revision: https://phabricator.services.mozilla.com/D160254
This commit is contained in:
Paul Zuehlcke 2022-11-01 13:34:56 +00:00
Родитель 9189ff3f6f
Коммит 2cbc80b675
7 изменённых файлов: 230 добавлений и 8 удалений

Просмотреть файл

@ -2749,6 +2749,8 @@ pref("browser.pdfjs.feature-tour", "{\"screen\":\"FEATURE_CALLOUT_1\",\"complete
// StaticPrefList.yaml for a description of the prefs.
#ifdef NIGHTLY_BUILD
pref("cookiebanners.service.mode.privateBrowsing", 1);
// Enables the cookie banner desktop UI.
pref("cookiebanners.ui.desktop.enabled", true);
#endif
// We only want to enable this pref for Desktop nightlies.

Просмотреть файл

@ -1057,6 +1057,183 @@ let SocialTracking = new (class SocialTrackingProtection extends ProtectionCateg
}
})();
/**
* Singleton to manage the cookie banner feature section in the protections
* panel.
*/
let cookieBannerSection = new (class {
// Check if this is a private window. We don't expect PBM state to change
// during the lifetime of this window.
#isPrivateBrowsing = PrivateBrowsingUtils.isWindowPrivate(window);
constructor() {
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_serviceModePref",
"cookiebanners.service.mode",
Ci.nsICookieBannerService.MODE_DISABLED
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_serviceModePrefPrivateBrowsing",
"cookiebanners.service.mode.privateBrowsing",
Ci.nsICookieBannerService.MODE_DISABLED
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_uiDisabled",
"cookiebanners.ui.desktop.enabled",
false
);
}
/**
* Initialize or update the cookie banner handling section state. To be called
* initially or whenever the panel opens for a new site.
*/
updateSection({ hostForDisplay }) {
let showSection = this.#shouldShowSection();
for (let el of [
this.#cookieBannerSection,
this.#cookieBannerSectionSeparator,
]) {
el.toggleAttribute("uiDisabled", !showSection);
}
if (showSection) {
// If section is visible also update the switch.
this.#updateSwitchState({ hostForDisplay });
}
}
/**
* Handler for clicks on the cookie banner per-site toggle.
*/
onCookieBannerSwitchCommand() {
// Update the switch UI state.
let newState = this.#cookieBannerSwitch.toggleAttribute("enabled");
// Update the switch label UI state.
this.#cookieBannerSection.toggleAttribute("hasException", !newState);
if (newState) {
// Enable the feature for the current site, this means clearing the
// per-site preference so we revert to global settings.
Services.cookieBanners.removeDomainPref(
gBrowser.currentURI,
this.#isPrivateBrowsing
);
} else {
// Disable the feature for the current site by setting an exception.
Services.cookieBanners.setDomainPref(
gBrowser.currentURI,
Ci.nsICookieBannerService.MODE_DISABLED,
this.#isPrivateBrowsing
);
}
this.#updateSwitchState({ hasException: !newState });
}
/**
* Update the UI state of the cookie banner feature switch.
* @param {*} options
* @param {boolean} [options.hasException] - Whether the current site has an
* exception from the cookie banner mechanism.
* @param {string} [options.hostForDisplay] - The host to expose via the switch
* label.
*/
#updateSwitchState({
hasException = this.#hasException,
hostForDisplay = gIdentityHandler.getHostForDisplay(),
}) {
// Switch state
this.#cookieBannerSwitch.toggleAttribute("enabled", !hasException);
// Switch label
this.#cookieBannerSection.toggleAttribute("hasException", hasException);
// Give the button an accessible label for screen readers.
// TODO: integrate this with fluent for the final UX.
if (hasException) {
this.#cookieBannerSwitch.setAttribute(
"aria-label",
"Enable cookie banner handling for " + hostForDisplay
);
} else {
this.#cookieBannerSwitch.setAttribute(
"aria-label",
"Disable cookie banner handling for " + hostForDisplay
);
}
}
/**
* Determines whether the cookie banner handling section should be shown.
* @returns {boolean} - true if the section should be shown, false otherwise.
*/
#shouldShowSection() {
// UI is globally disabled by pref.
if (!this._uiDisabled) {
return false;
}
let mode;
if (this.#isPrivateBrowsing) {
mode = this._serviceModePrefPrivateBrowsing;
} else {
mode = this._serviceModePref;
}
// Only show the section if the feature is enabled for the normal or PBM
// window.
return mode != Ci.nsICookieBannerService.MODE_DISABLED;
}
/**
* Tests if the current site has an exception from the default cookie banner
* handling mode. Currently that means the feature is disabled for that site.
*/
get #hasException() {
let pref = Services.cookieBanners.getDomainPref(
gBrowser.currentURI,
this.#isPrivateBrowsing
);
return pref == Ci.nsICookieBannerService.MODE_DISABLED;
}
// Element getters
#cookieBannerSectionEl;
get #cookieBannerSection() {
if (this.#cookieBannerSectionEl) {
return this.#cookieBannerSectionEl;
}
return (this.#cookieBannerSectionEl = document.getElementById(
"protections-popup-cookie-banner-section"
));
}
#cookieBannerSectionSeparatorEl;
get #cookieBannerSectionSeparator() {
if (this.#cookieBannerSectionSeparatorEl) {
return this.#cookieBannerSectionSeparatorEl;
}
return (this.#cookieBannerSectionSeparatorEl = document.getElementById(
"protections-popup-cookie-banner-section-separator"
));
}
#cookieBannerSwitchEl;
get #cookieBannerSwitch() {
if (this.#cookieBannerSwitchEl) {
return this.#cookieBannerSwitchEl;
}
return (this.#cookieBannerSwitchEl = document.getElementById(
"protections-popup-cookie-banner-switch"
));
}
})();
/**
* Utility object to handle manipulations of the protections indicators in the UI
*/
@ -1867,6 +2044,8 @@ var gProtectionsHandler = {
this._protectionsPopup.removeAttribute("milestone");
}
cookieBannerSection.updateSection({ hostForDisplay: host });
this._protectionsPopup.toggleAttribute("detected", this.anyDetected);
this._protectionsPopup.toggleAttribute("blocking", this.anyBlocking);
this._protectionsPopup.toggleAttribute("hasException", this.hasException);
@ -2018,6 +2197,10 @@ var gProtectionsHandler = {
delete this._TPSwitchCommanding;
},
onCookieBannerSwitchCommand() {
cookieBannerSection.onCookieBannerSwitchCommand();
},
setTrackersBlockedCounter(trackerCount) {
let forms = gNavigatorBundle.getString(
"protections.footer.blockedTrackerCounter.description"

Просмотреть файл

@ -71,6 +71,7 @@
<link rel="localization" href="browser/browserSets.ftl"/>
<link rel="localization" href="browser/menubar.ftl"/>
<link rel="localization" href="browser/protectionsPanel.ftl"/>
<link rel="localization" href="preview/protectionsPanel.ftl"/>
<link rel="localization" href="browser/appmenu.ftl"/>
<link rel="localization" href="browser/panelUI.ftl"/>
<link rel="localization" href="preview/identityCredentialNotification.ftl"/>

Просмотреть файл

@ -0,0 +1,8 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
### These are additional strings for the protections panel which is opened through the shield icon in the url bar.
protections-panel-cookie-banner-handling-on-header = Auto Cookie Banner Handling is ON for this site
protections-panel-cookie-banner-handling-off-header = Auto Cookie Banner Handling is OFF for this site

Просмотреть файл

@ -41,12 +41,12 @@
<toolbarseparator></toolbarseparator>
<vbox id="protections-popup-main-body" class="panel-subview-body">
<hbox id="protections-popup-tp-switch-section" class="protections-popup-section">
<hbox id="protections-popup-tp-switch-section" class="protections-popup-section protections-popup-switch-section">
<vbox class="protections-popup-tp-switch-label-box" flex="1" align="start">
<label class="protections-popup-tp-switch-on-header"
<label class="protections-popup-switch-header protections-popup-tp-switch-on-header"
role="heading"
aria-level="2" data-l10n-id="protections-panel-etp-on-header"></label>
<label class="protections-popup-tp-switch-off-header"
<label class="protections-popup-switch-header protections-popup-tp-switch-off-header"
role="heading"
aria-level="2" data-l10n-id="protections-panel-etp-off-header"></label>
<label id="protections-popup-tp-switch-breakage-link"
@ -65,6 +65,24 @@
</vbox>
</hbox>
<toolbarseparator id="protections-popup-cookie-banner-section-separator"></toolbarseparator>
<hbox id="protections-popup-cookie-banner-section" class="protections-popup-section protections-popup-switch-section" uiDisabled="true">
<vbox class="protections-popup-tp-switch-label-box" flex="1" align="start">
<label class="protections-popup-switch-header protections-popup-cookie-banner-switch-on-header"
role="heading"
aria-level="2" data-l10n-id="protections-panel-cookie-banner-handling-on-header"></label>
<label class="protections-popup-switch-header protections-popup-cookie-banner-switch-off-header"
role="heading"
aria-level="2" data-l10n-id="protections-panel-cookie-banner-handling-off-header"></label>
</vbox>
<vbox class="protections-popup-tp-switch-box">
<toolbarbutton id="protections-popup-cookie-banner-switch"
class="protections-popup-tp-switch"
enabled="false"
oncommand="gProtectionsHandler.onCookieBannerSwitchCommand()" />
</vbox>
</hbox>
<!-- Tracking Protection Section -->
<toolbarseparator></toolbarseparator>
<vbox id="tracking-protection-container" class="protections-popup-section">

Просмотреть файл

@ -15,6 +15,7 @@
preview/originControls.ftl (../components/extensions/originControls.ftl)
preview/unifiedExtensions.ftl (../components/extensions/unifiedExtensions.ftl)
preview/identityCredentialNotification.ftl (../components/credentialmanager/identityCredentialNotification.ftl)
preview/protectionsPanel.ftl (../base/content/protectionsPanel.ftl)
browser (%browser/**/*.ftl)
@AB_CD@.jar:

Просмотреть файл

@ -571,6 +571,16 @@
display: none;
}
#protections-popup-cookie-banner-section[hasException] .protections-popup-cookie-banner-switch-on-header,
#protections-popup-cookie-banner-section:not([hasException]) .protections-popup-cookie-banner-switch-off-header {
display: none;
}
#protections-popup-cookie-banner-section[uiDisabled],
#protections-popup-cookie-banner-section-separator[uiDisabled]{
display: none;
}
#protections-popup-toast-panel-tp-on-desc,
#protections-popup-toast-panel-tp-off-desc {
display: none;
@ -589,13 +599,12 @@
/* This is needed in order to show a correct height if the 'Site not working?'
link is not displaying. */
#protections-popup-tp-switch-section[short] > .protections-popup-tp-switch-label-box,
#protections-popup-tp-switch-section[short] > .protections-popup-tp-switch-box {
.protections-popup-switch-section[short] > .protections-popup-tp-switch-label-box,
.protections-popup-switch-section[short] > .protections-popup-tp-switch-box {
min-height: 30px;
}
.protections-popup-tp-switch-on-header,
.protections-popup-tp-switch-off-header {
.protections-popup-switch-header {
font-weight: 600;
}
@ -772,7 +781,7 @@
}
.protections-popup-section-header,
#protections-popup-tp-switch-section,
.protections-popup-switch-section,
#protections-popup-siteNotWorkingView-header {
padding: var(--arrowpanel-menuitem-padding);
margin: var(--arrowpanel-menuitem-margin);