зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1800675 - Add about:preferences entry for cookie banner handling. r=fluent-reviewers,flod,mconley
Differential Revision: https://phabricator.services.mozilla.com/D164632
This commit is contained in:
Родитель
e65ec6d643
Коммит
128ed3a6e6
|
@ -0,0 +1,11 @@
|
|||
# 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/.
|
||||
|
||||
## Privacy Section - Cookie Banner Handling
|
||||
|
||||
cookie-banner-handling-header = Cookie Banner Reduction
|
||||
cookie-banner-reject-accept = { -brand-short-name } automatically tries to reject cookie requests on cookie banners. If a reject option isn’t available, { -brand-short-name } may accept all cookies to dismiss the banner.
|
||||
cookie-banner-learn-more = Learn More
|
||||
forms-handle-cookie-banners =
|
||||
.label = Reduce Cookie Banners
|
|
@ -55,6 +55,7 @@
|
|||
<link rel="localization" href="security/certificates/deviceManager.ftl"/>
|
||||
<link rel="localization" href="security/certificates/certManager.ftl"/>
|
||||
<link rel="localization" href="preview/firefoxSuggest.ftl"/>
|
||||
<link rel="localization" href="preview/cookieBannerPreferences.ftl"/>
|
||||
|
||||
<link rel="shortcut icon" href="chrome://global/skin/icons/settings.svg"/>
|
||||
|
||||
|
|
|
@ -383,6 +383,25 @@
|
|||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Cookie Banner Handling -->
|
||||
<groupbox id="cookieBannerHandlingGroup" data-category="panePrivacy" data-subcategory="cookiebanner" hidden="true">
|
||||
<label><html:h2 data-l10n-id="cookie-banner-handling-header" /></label>
|
||||
<vbox flex="1">
|
||||
<hbox>
|
||||
<description>
|
||||
<html:span id="cookieBannerReductionExplanation" class="tail-with-learn-more" data-l10n-id="cookie-banner-reject-accept" ></html:span>
|
||||
<label id="cookieBannerHandlingLearnMore" class="learnMore" is="text-link" data-l10n-id="cookie-banner-learn-more"></label>
|
||||
</description>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox id="handleCookieBanners"
|
||||
preference="cookiebanners.service.mode"
|
||||
data-l10n-id="forms-handle-cookie-banners"
|
||||
flex="1" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Passwords -->
|
||||
<groupbox id="passwordsGroup" orient="vertical" data-category="panePrivacy" data-subcategory="logins" hidden="true">
|
||||
<label><html:h2 data-l10n-id="pane-privacy-logins-and-passwords-header" data-l10n-attrs="searchkeywords"/></label>
|
||||
|
|
|
@ -193,6 +193,10 @@ Preferences.addAll([
|
|||
// Quick Actions
|
||||
{ id: "browser.urlbar.quickactions.showPrefs", type: "bool" },
|
||||
{ id: "browser.urlbar.suggest.quickactions", type: "bool" },
|
||||
|
||||
// Cookie Banner Handling
|
||||
{ id: "cookiebanners.ui.desktop.enabled", type: "bool" },
|
||||
{ id: "cookiebanners.service.mode", type: "int" },
|
||||
]);
|
||||
|
||||
// Study opt out
|
||||
|
@ -754,6 +758,8 @@ var gPrivacyPane = {
|
|||
"storage-permissions";
|
||||
document.getElementById("siteDataLearnMoreLink").setAttribute("href", url);
|
||||
|
||||
this.initCookieBannerHandling();
|
||||
|
||||
let notificationInfoURL =
|
||||
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
|
||||
document
|
||||
|
@ -1982,6 +1988,92 @@ var gPrivacyPane = {
|
|||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the cookie banner handling subgroup on the privacy pane.
|
||||
*
|
||||
* This UI is shown if the "cookiebanners.ui.desktop.enabled" pref is true.
|
||||
*
|
||||
* The cookie banner handling checkbox tracks the state of the integer-valued
|
||||
* "cookiebanners.service.mode" pref: unchecked if the value is either
|
||||
* nsICookieBannerService.MODE_DISABLED, meaning the feature is turned off, or
|
||||
* nsICookieBannerService.MODE_DETECT_ONLY, which is used to allow us to
|
||||
* advertise the feature to the user via an onboarding doorhanger.
|
||||
*
|
||||
* If the user checks the checkbox, the pref value is set to
|
||||
* nsICookieBannerService.MODE_REJECT_OR_ACCEPT.
|
||||
*
|
||||
* If the user unchecks the checkbox, the mode pref value is set to
|
||||
* nsICookieBannerService.MODE_DISABLED.
|
||||
*
|
||||
* Advanced users can choose other int-valued modes via about:config.
|
||||
*/
|
||||
initCookieBannerHandling() {
|
||||
this._initCookieBannerHandlingLearnMore();
|
||||
|
||||
setSyncFromPrefListener("handleCookieBanners", () =>
|
||||
this.readCookieBannerMode()
|
||||
);
|
||||
setSyncToPrefListener("handleCookieBanners", () =>
|
||||
this.writeCookieBannerMode()
|
||||
);
|
||||
|
||||
let preference = Preferences.get("cookiebanners.ui.desktop.enabled");
|
||||
preference.on("change", () => this.updateCookieBannerHandlingVisibility());
|
||||
|
||||
this.updateCookieBannerHandlingVisibility();
|
||||
},
|
||||
|
||||
_initCookieBannerHandlingLearnMore() {
|
||||
let url =
|
||||
Services.urlFormatter.formatURLPref("app.support.baseURL") +
|
||||
"cookie-banner-reduction";
|
||||
let learnMore = document.getElementById("cookieBannerHandlingLearnMore");
|
||||
learnMore.setAttribute("href", url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reads the cookiebanners.service.mode preference value and updates
|
||||
* the cookie banner handling checkbox accordingly.
|
||||
*/
|
||||
readCookieBannerMode() {
|
||||
let mode = Preferences.get("cookiebanners.service.mode").value;
|
||||
let disabledModes = [
|
||||
Ci.nsICookieBannerService.MODE_DISABLED,
|
||||
Ci.nsICookieBannerService.MODE_DETECT_ONLY,
|
||||
];
|
||||
let isEnabled = !disabledModes.includes(mode);
|
||||
return isEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Translates user clicks on the cookie banner handling checkbox to the
|
||||
* corresponding integer-valued cookie banner mode preference.
|
||||
*/
|
||||
writeCookieBannerMode() {
|
||||
let checkbox = document.getElementById("handleCookieBanners");
|
||||
let mode = checkbox.checked
|
||||
? Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT
|
||||
: Ci.nsICookieBannerService.MODE_DISABLED;
|
||||
return mode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows or hides the cookie banner handling section based on the value of
|
||||
* the "cookiebanners.ui.desktop.enabled" pref.
|
||||
*/
|
||||
updateCookieBannerHandlingVisibility() {
|
||||
let groupbox = document.getElementById("cookieBannerHandlingGroup");
|
||||
let isEnabled = Preferences.get("cookiebanners.ui.desktop.enabled").value;
|
||||
|
||||
// Because the top-level pane showing code unsets the hidden attribute, we
|
||||
// manually hide the section when cookie banner handling is preffed off.
|
||||
if (isEnabled) {
|
||||
groupbox.removeAttribute("style");
|
||||
} else {
|
||||
groupbox.setAttribute("style", "display: none !important");
|
||||
}
|
||||
},
|
||||
|
||||
// ADDRESS BAR
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,6 +101,7 @@ skip-if = true
|
|||
[browser_proxy_backup.js]
|
||||
[browser_privacypane_2.js]
|
||||
[browser_privacypane_3.js]
|
||||
[browser_privacy_cookieBannerHandling.js]
|
||||
[browser_privacy_firefoxSuggest.js]
|
||||
[browser_privacy_passwordGenerationAndAutofill.js]
|
||||
[browser_privacy_relayIntegration.js]
|
||||
|
|
|
@ -36,6 +36,15 @@ function checkElements(expectedPane) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Cookie Banner Handling is currently disabled by default (bug 1800679)
|
||||
if (element.id == "cookieBannerHandlingGroup") {
|
||||
is_element_hidden(
|
||||
element,
|
||||
"Disabled cookieBannerHandlingGroup should be hidden"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update prefs are hidden when running an MSIX build
|
||||
if (
|
||||
updatePrefContainers.includes(element.id) &&
|
||||
|
|
|
@ -33,6 +33,13 @@ async function runTest(win) {
|
|||
await win.gotoPref("panePrivacy");
|
||||
for (let element of elements) {
|
||||
let attributeValue = element.getAttribute("data-category");
|
||||
|
||||
// Ignore the cookie banner handling section, as it is currently preffed
|
||||
// off by default (bug 1800679).
|
||||
if (element.id === "cookieBannerHandlingGroup") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attributeValue == "panePrivacy") {
|
||||
is_element_visible(element, "HTTPSOnly should be visible");
|
||||
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This file tests the Privacy pane's Cookie Banner Handling UI.
|
||||
|
||||
"use strict";
|
||||
|
||||
const FEATURE_PREF = "cookiebanners.ui.desktop.enabled";
|
||||
const MODE_PREF = "cookiebanners.service.mode";
|
||||
|
||||
const GROUPBOX_ID = "cookieBannerHandlingGroup";
|
||||
const CHECKBOX_ID = "handleCookieBanners";
|
||||
|
||||
// Test the section is hidden on page load if the feature pref is disabled.
|
||||
add_task(async function test_section_hidden_when_feature_flag_disabled() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, false],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_DISABLED],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let groupbox = browser.contentDocument.getElementById(GROUPBOX_ID);
|
||||
is_element_hidden(groupbox, "#cookieBannerHandlingGroup is hidden");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test the section is shown on page load if the feature pref is enabled.
|
||||
add_task(async function test_section_shown_when_feature_flag_enabled() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_DISABLED],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let groupbox = browser.contentDocument.getElementById(GROUPBOX_ID);
|
||||
is_element_visible(groupbox, "#cookieBannerHandlingGroup is visible");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test the checkbox is unchecked in DISABLED mode.
|
||||
add_task(async function test_checkbox_unchecked_disabled_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_DISABLED],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let checkbox = browser.contentDocument.getElementById(CHECKBOX_ID);
|
||||
ok(!checkbox.checked, "checkbox is not checked in DISABLED mode");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test the checkbox is unchecked in DETECT_ONLY mode.
|
||||
add_task(async function test_checkbox_unchecked_detect_only_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_DETECT_ONLY],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let checkbox = browser.contentDocument.getElementById(CHECKBOX_ID);
|
||||
ok(!checkbox.checked, "checkbox is not checked in DETECT_ONLY mode");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test the checkbox is checked in REJECT_OR_ACCEPT mode.
|
||||
add_task(async function test_checkbox_checked_reject_or_accept_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let checkbox = browser.contentDocument.getElementById(CHECKBOX_ID);
|
||||
ok(checkbox.checked, "checkbox is checked in REJECT_OR_ACCEPT mode");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test the checkbox is checked in REJECT mode.
|
||||
add_task(async function test_checkbox_checked_reject_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_REJECT],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let checkbox = browser.contentDocument.getElementById(CHECKBOX_ID);
|
||||
ok(checkbox.checked, "checkbox is checked in REJECT mode");
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Test that toggling the checkbox toggles the mode pref value as expected.
|
||||
add_task(async function test_checkbox_modifies_mode_pref() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[FEATURE_PREF, true],
|
||||
[MODE_PREF, Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT],
|
||||
],
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:preferences#privacy" },
|
||||
async function(browser) {
|
||||
let checkboxSelector = "#" + CHECKBOX_ID;
|
||||
let checkbox = browser.contentDocument.querySelector(checkboxSelector);
|
||||
let section = browser.contentDocument.getElementById(GROUPBOX_ID);
|
||||
|
||||
section.scrollIntoView();
|
||||
|
||||
Assert.ok(checkbox.checked, "initially, the checkbox should be checked");
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
checkboxSelector,
|
||||
{},
|
||||
browser
|
||||
);
|
||||
Assert.ok(!checkbox.checked, "checkbox should be unchecked");
|
||||
Assert.equal(
|
||||
Ci.nsICookieBannerService.MODE_DISABLED,
|
||||
Services.prefs.getIntPref(MODE_PREF),
|
||||
"cookie banner handling mode should be set to DISABLED mode after unchecking the checkbox"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
checkboxSelector,
|
||||
{},
|
||||
browser
|
||||
);
|
||||
Assert.ok(checkbox.checked, "checkbox should be checked");
|
||||
Assert.equal(
|
||||
Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
|
||||
Services.prefs.getIntPref(MODE_PREF),
|
||||
"cookie banner handling mode should be set to REJECT_OR_ACCEPT mode after checking the checkbox"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -131,11 +131,13 @@ async function runSearchInput(input) {
|
|||
|
||||
async function evaluateSearchResults(
|
||||
keyword,
|
||||
searchReults,
|
||||
searchResults,
|
||||
includeExperiments = false
|
||||
) {
|
||||
searchReults = Array.isArray(searchReults) ? searchReults : [searchReults];
|
||||
searchReults.push("header-searchResults");
|
||||
searchResults = Array.isArray(searchResults)
|
||||
? searchResults
|
||||
: [searchResults];
|
||||
searchResults.push("header-searchResults");
|
||||
|
||||
await runSearchInput(keyword);
|
||||
|
||||
|
@ -145,7 +147,7 @@ async function evaluateSearchResults(
|
|||
if (!includeExperiments && child.id?.startsWith("pane-experimental")) {
|
||||
continue;
|
||||
}
|
||||
if (searchReults.includes(child.id)) {
|
||||
if (searchResults.includes(child.id)) {
|
||||
is_element_visible(child, `${child.id} should be in search results`);
|
||||
} else if (child.id) {
|
||||
is_element_hidden(child, `${child.id} should not be in search results`);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
preview/firefoxSuggest.ftl (../components/urlbar/content/firefoxSuggest.ftl)
|
||||
preview/identityCredentialNotification.ftl (../components/credentialmanager/identityCredentialNotification.ftl)
|
||||
preview/protectionsPanel.ftl (../base/content/protectionsPanel.ftl)
|
||||
preview/cookieBannerPreferences.ftl (../components/preferences/cookieBannerPreferences.ftl)
|
||||
locales-preview/migrationWizard.ftl (../locales-preview/migrationWizard.ftl)
|
||||
browser (%browser/**/*.ftl)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче