Bug 1474238 - Add a "report breakage" dialog for Tracking Protection. r=Paolo
MozReview-Commit-ID: 26q5PYLUZGS
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1488,16 +1488,22 @@ pref("browser.ping-centre.production.end
pref("media.gmp-provider.enabled", true);
pref("browser.contentblocking.enabled", true);
#ifdef NIGHTLY_BUILD
pref("browser.contentblocking.ui.enabled", true);
#else
pref("browser.contentblocking.ui.enabled", false);
#endif
+#ifdef NIGHTLY_BUILD
+pref("browser.contentblocking.reportBreakage.enabled", true);
+#else
+pref("browser.contentblocking.reportBreakage.enabled", false);
+#endif
+pref("browser.contentblocking.reportBreakage.url", "https://tracking-protection-issues.herokuapp.com/new");
pref("privacy.trackingprotection.introCount", 0);
pref("privacy.trackingprotection.introURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tracking-protection/start/");
// Always enable newtab segregation using containers
pref("privacy.usercontext.about_newtab_segregation.enabled", true);
// Enable Contextual Identity Containers
#ifdef NIGHTLY_BUILD
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -127,16 +127,18 @@ var TrackingProtection = {
var ContentBlocking = {
// If the user ignores the doorhanger, we stop showing it after some time.
MAX_INTROS: 20,
PREF_ENABLED: "browser.contentblocking.enabled",
PREF_UI_ENABLED: "browser.contentblocking.ui.enabled",
PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
+ PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
+ PREF_REPORT_BREAKAGE_URL: "browser.contentblocking.reportBreakage.url",
content: null,
icon: null,
activeTooltipText: null,
disabledTooltipText: null,
get appMenuLabel() {
delete this.appMenuLabel;
return this.appMenuLabel = document.getElementById("appMenu-tp-label");
@@ -199,16 +201,33 @@ var ContentBlocking = {
init() {
let $ = selector => document.querySelector(selector);
this.content = $("#identity-popup-content-blocking-content");
this.icon = $("#tracking-protection-icon");
this.iconBox = $("#tracking-protection-icon-box");
this.animatedIcon = $("#tracking-protection-icon-animatable-image");
this.animatedIcon.addEventListener("animationend", () => this.iconBox.removeAttribute("animate"));
+ this.identityPopupMultiView = $("#identity-popup-multiView");
+ this.reportBreakageButton = $("#identity-popup-content-blocking-report-breakage");
+ this.reportBreakageURL = $("#identity-popup-breakageReportView-collection-url");
+ this.reportBreakageUA = $("#identity-popup-breakageReportView-collection-userAgent");
+ this.reportBreakageLearnMore = $("#identity-popup-breakageReportView-learn-more");
+
+ let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
+ this.reportBreakageLearnMore.href = baseURL + "tracking-protection-pbm";
+
+ this.updateReportBreakageUI = () => {
+ this.reportBreakageButton.hidden = !Services.prefs.getBoolPref(this.PREF_REPORT_BREAKAGE_ENABLED);
+ };
+
+ this.updateReportBreakageUI();
+
+ Services.prefs.addObserver(this.PREF_REPORT_BREAKAGE_ENABLED, this.updateReportBreakageUI);
+
this.updateAnimationsEnabled = () => {
this.iconBox.toggleAttribute("animationsenabled",
Services.prefs.getBoolPref(this.PREF_ANIMATIONS_ENABLED, false));
};
for (let blocker of this.blockers) {
if (blocker.init) {
blocker.init();
@@ -236,16 +255,17 @@ var ContentBlocking = {
uninit() {
for (let blocker of this.blockers) {
if (blocker.uninit) {
blocker.uninit();
}
}
Services.prefs.removeObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
+ Services.prefs.removeObserver(this.PREF_REPORT_BREAKAGE_ENABLED, this.updateReportBreakageUI);
},
get enabled() {
return this.contentBlockingUIEnabled ? this.contentBlockingEnabled : TrackingProtection.enabled;
},
updateEnabled() {
this.content.toggleAttribute("enabled", this.enabled);
@@ -281,16 +301,74 @@ var ContentBlocking = {
document.getElementById("identity-popup").hidePopup();
BrowserReload();
},
openPreferences(origin) {
openPreferences("privacy-trackingprotection", { origin });
},
+ backToMainView() {
+ this.identityPopupMultiView.goBack();
+ },
+
+ submitBreakageReport() {
+ document.getElementById("identity-popup").hidePopup();
+
+ let reportEndpoint = Services.prefs.getStringPref(this.PREF_REPORT_BREAKAGE_URL);
+ if (!reportEndpoint) {
+ return;
+ }
+
+ let formData = new FormData();
+ formData.set("title", this.reportURI.host);
+
+ // Leave the ? at the end of the URL to signify that this URL had its query stripped.
+ let urlWithoutQuery = this.reportURI.asciiSpec.replace(this.reportURI.query, "");
+ let body = `Full URL: ${urlWithoutQuery}\n`;
+ body += `userAgent: ${this.reportBreakageUA.textContent}\n`;
+
+ body += "\n**Preferences**\n";
+ body += `${TrackingProtection.PREF_ENABLED_GLOBALLY}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_ENABLED_GLOBALLY)}\n`;
+ body += `${TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS)}\n`;
+ body += `urlclassifier.trackingTable: ${Services.prefs.getStringPref("urlclassifier.trackingTable")}\n`;
+ body += `network.http.referer.defaultPolicy: ${Services.prefs.getIntPref("network.http.referer.defaultPolicy")}\n`;
+ body += `network.http.referer.defaultPolicy.pbmode: ${Services.prefs.getIntPref("network.http.referer.defaultPolicy.pbmode")}\n`;
+ body += `network.cookie.cookieBehavior: ${Services.prefs.getIntPref("network.cookie.cookieBehavior")}\n`;
+ body += `network.cookie.lifetimePolicy: ${Services.prefs.getIntPref("network.cookie.lifetimePolicy")}\n`;
+ body += `privacy.restrict3rdpartystorage.expiration: ${Services.prefs.getIntPref("privacy.restrict3rdpartystorage.expiration")}\n`;
+ body += `${FastBlock.PREF_ENABLED}: ${Services.prefs.getBoolPref(FastBlock.PREF_ENABLED)}\n`;
+ body += `browser.fastblock.timeout: ${Services.prefs.getIntPref("browser.fastblock.timeout")}\n`;
+
+ let comments = document.getElementById("identity-popup-breakageReportView-collection-comments");
+ body += "\n**Comments**\n" + comments.value;
+
+ formData.set("body", body);
+
+ fetch(reportEndpoint, {
+ method: "POST",
+ credentials: "omit",
+ body: formData,
+ }).then(function(response) {
+ if (!response.ok) {
+ Cu.reportError(`Content Blocking report to ${reportEndpoint} failed with status ${response.status}`);
+ }
+ }).catch(Cu.reportError);
+ },
+
+ showReportBreakageSubview() {
+ // Save this URI to make sure that the user really only submits the location
+ // they see in the report breakage dialog.
+ this.reportURI = gBrowser.currentURI;
+ let urlWithoutQuery = this.reportURI.asciiSpec.replace("?" + this.reportURI.query, "");
+ this.reportBreakageURL.textContent = urlWithoutQuery;
+ this.reportBreakageUA.textContent = navigator.userAgent;
+ this.identityPopupMultiView.showSubView("identity-popup-breakageReportView");
+ },
+
eventsHistogramAdd(value) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
Services.telemetry.getHistogramById("TRACKING_PROTECTION_EVENTS").add(value);
},
shieldHistogramAdd(value) {
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -12,10 +12,11 @@ support-files =
[browser_trackingUI_appMenu_toggle.js]
[browser_trackingUI_fetch.js]
support-files =
file_trackingUI_fetch.html
file_trackingUI_fetch.js
file_trackingUI_fetch.js^headers^
[browser_trackingUI_open_preferences.js]
[browser_trackingUI_pbmode_exceptions.js]
+[browser_trackingUI_report_breakage.js]
[browser_trackingUI_state.js]
[browser_trackingUI_telemetry.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
@@ -0,0 +1,239 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
+const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
+
+const CB_PREF = "browser.contentblocking.enabled";
+const TP_PREF = "privacy.trackingprotection.enabled";
+const PREF_REPORT_BREAKAGE_ENABLED = "browser.contentblocking.reportBreakage.enabled";
+const PREF_REPORT_BREAKAGE_URL = "browser.contentblocking.reportBreakage.url";
+
+let {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js", {});
+let {CommonUtils} = ChromeUtils.import("resource://services-common/utils.js", {});
+let {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm", {});
+
+add_task(async function setup() {
+ await UrlClassifierTestUtils.addTestTrackers();
+});
+
+function openIdentityPopup() {
+ let mainView = document.getElementById("identity-popup-mainView");
+ let viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
+ gIdentityHandler._identityBox.click();
+ return viewShown;
+}
+
+add_task(async function testReportBreakageVisibility() {
+ let scenarios = [
+ {
+ url: TRACKING_PAGE,
+ prefs: {
+ "browser.contentblocking.enabled": true,
+ "privacy.trackingprotection.enabled": true,
+ "browser.contentblocking.reportBreakage.enabled": true,
+ },
+ buttonVisible: true,
+ },
+ {
+ url: TRACKING_PAGE,
+ hasException: true,
+ prefs: {
+ "browser.contentblocking.enabled": true,
+ "privacy.trackingprotection.enabled": true,
+ "browser.contentblocking.reportBreakage.enabled": true,
+ },
+ buttonVisible: true,
+ },
+ {
+ url: TRACKING_PAGE,
+ prefs: {
+ "browser.contentblocking.enabled": false,
+ "privacy.trackingprotection.enabled": true,
+ "browser.contentblocking.reportBreakage.enabled": true,
+ },
+ buttonVisible: false,
+ },
+ {
+ url: TRACKING_PAGE,
+ prefs: {
+ "browser.contentblocking.enabled": true,
+ "privacy.trackingprotection.enabled": true,
+ "browser.contentblocking.reportBreakage.enabled": false,
+ },
+ buttonVisible: false,
+ },
+ {
+ url: BENIGN_PAGE,
+ prefs: {
+ "browser.contentblocking.enabled": true,
+ "privacy.trackingprotection.enabled": true,
+ "browser.contentblocking.reportBreakage.enabled": true,
+ },
+ buttonVisible: false,
+ },
+ ];
+
+ for (let scenario of scenarios) {
+ for (let pref in scenario.prefs) {
+ Services.prefs.setBoolPref(pref, scenario.prefs[pref]);
+ }
+
+ let uri = Services.io.newURI(scenario.url);
+ if (scenario.hasException) {
+ Services.perms.add(uri, "trackingprotection", Services.perms.ALLOW_ACTION);
+ }
+
+ await BrowserTestUtils.withNewTab(scenario.url, async function() {
+ await openIdentityPopup();
+
+ let reportBreakageButton = document.getElementById("identity-popup-content-blocking-report-breakage");
+ is(BrowserTestUtils.is_visible(reportBreakageButton), scenario.buttonVisible,
+ "report breakage button has the correct visibility");
+ });
+
+ Services.perms.remove(uri, "trackingprotection");
+ for (let pref in scenario.prefs) {
+ Services.prefs.clearUserPref(pref);
+ }
+ }
+});
+
+add_task(async function testReportBreakageCancel() {
+ Services.prefs.setBoolPref(TP_PREF, true);
+ Services.prefs.setBoolPref(CB_PREF, true);
+ Services.prefs.setBoolPref(PREF_REPORT_BREAKAGE_ENABLED, true);
+
+ await BrowserTestUtils.withNewTab(TRACKING_PAGE, async function() {
+ await openIdentityPopup();
+
+ let reportBreakageButton = document.getElementById("identity-popup-content-blocking-report-breakage");
+ ok(BrowserTestUtils.is_visible(reportBreakageButton), "report breakage button is visible");
+ let reportBreakageView = document.getElementById("identity-popup-breakageReportView");
+ let viewShown = BrowserTestUtils.waitForEvent(reportBreakageView, "ViewShown");
+ reportBreakageButton.click();
+ await viewShown;
+
+ ok(true, "Report breakage view was shown");
+
+ let mainView = document.getElementById("identity-popup-mainView");
+ viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
+ let cancelButton = document.getElementById("identity-popup-breakageReportView-cancel");
+ cancelButton.click();
+ await viewShown;
+
+ ok(true, "Main view was shown");
+ });
+
+ Services.prefs.clearUserPref(CB_PREF);
+ Services.prefs.clearUserPref(TP_PREF);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
+});
+
+add_task(async function testReportBreakage() {
+ // Setup a mock server for receiving breakage reports.
+ let server = new HttpServer();
+ server.start(-1);
+ let i = server.identity;
+ let path = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort + "/";
+
+ Services.prefs.setBoolPref(TP_PREF, true);
+ Services.prefs.setBoolPref(CB_PREF, true);
+ Services.prefs.setBoolPref(PREF_REPORT_BREAKAGE_ENABLED, true);
+ Services.prefs.setStringPref(PREF_REPORT_BREAKAGE_URL, path);
+
+ // Make sure that we correctly strip the query.
+ let url = TRACKING_PAGE + "?a=b&1=abc&unicode=🦊";
+ await BrowserTestUtils.withNewTab(url, async function() {
+ await openIdentityPopup();
+
+ let reportBreakageButton = document.getElementById("identity-popup-content-blocking-report-breakage");
+ ok(BrowserTestUtils.is_visible(reportBreakageButton), "report breakage button is visible");
+ let reportBreakageView = document.getElementById("identity-popup-breakageReportView");
+ let viewShown = BrowserTestUtils.waitForEvent(reportBreakageView, "ViewShown");
+ reportBreakageButton.click();
+ await viewShown;
+
+ let submitButton = document.getElementById("identity-popup-breakageReportView-submit");
+ let reportURL = document.getElementById("identity-popup-breakageReportView-collection-url").textContent;
+ let reportUA = document.getElementById("identity-popup-breakageReportView-collection-userAgent").textContent;
+
+ is(reportURL, TRACKING_PAGE, "Shows the correct URL in the report UI.");
+ is(reportUA, navigator.userAgent, "Shows the correct user agent in the report UI.");
+
+ // Make sure that sending the report closes the identity popup.
+ let popuphidden = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
+
+ // Check that we're receiving a good report.
+ await new Promise(resolve => {
+ server.registerPathHandler("/", async (request, response) => {
+ is(request.method, "POST", "request was a post");
+
+ // Extract and "parse" the form data in the request body.
+ let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
+ let boundary = request.getHeader("Content-Type").match(/boundary=-+([^-]*)/i)[1];
+ let regex = new RegExp("-+" + boundary + "-*\\s+");
+ let sections = body.split(regex);
+
+ let prefs = [
+ "privacy.trackingprotection.enabled",
+ "privacy.trackingprotection.pbmode.enabled",
+ "urlclassifier.trackingTable",
+ "network.http.referer.defaultPolicy",
+ "network.http.referer.defaultPolicy.pbmode",
+ "network.cookie.cookieBehavior",
+ "network.cookie.lifetimePolicy",
+ "privacy.restrict3rdpartystorage.expiration",
+ "browser.fastblock.enabled",
+ "browser.fastblock.timeout",
+ ];
+ let prefsBody = "";
+
+ for (let pref of prefs) {
+ prefsBody += `${pref}: ${Preferences.get(pref)}\r\n`;
+ }
+
+ Assert.deepEqual(sections, [
+ "",
+ "Content-Disposition: form-data; name=\"title\"\r\n\r\ntracking.example.org\r\n",
+ "Content-Disposition: form-data; name=\"body\"\r\n\r\n" +
+ `Full URL: ${reportURL + "?"}\r\n` +
+ `userAgent: ${reportUA}\r\n\r\n` +
+ "**Preferences**\r\n" +
+ `${prefsBody}\r\n` +
+ "**Comments**\r\n" +
+ "This is a comment\r\n",
+ ""
+ ], "Should send the correct form data");
+
+ resolve();
+ });
+
+ let comments = document.getElementById("identity-popup-breakageReportView-collection-comments");
+ comments.value = "This is a comment";
+ submitButton.click();
+ });
+
+ await popuphidden;
+ });
+
+ // Stop the server.
+ await new Promise(r => server.stop(r));
+
+ Services.prefs.clearUserPref(CB_PREF);
+ Services.prefs.clearUserPref(TP_PREF);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
+});
+
+add_task(async function cleanup() {
+ // Clear prefs that are touched in this test again for sanity.
+ Services.prefs.clearUserPref(CB_PREF);
+ Services.prefs.clearUserPref(TP_PREF);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
+ Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
+
+ UrlClassifierTestUtils.cleanupTestTrackers();
+});
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -106,16 +106,20 @@
label="&trackingProtection.unblockPrivate4.label;"
accesskey="&trackingProtection.unblockPrivate4.accesskey;"
oncommand="ContentBlocking.disableForCurrentPage();" />
<button id="tracking-action-block"
class="tracking-protection-button"
label="&trackingProtection.block5.label;"
accesskey="&trackingProtection.block5.accesskey;"
oncommand="ContentBlocking.enableForCurrentPage();" />
+ <label id="identity-popup-content-blocking-report-breakage"
+ onclick="ContentBlocking.showReportBreakageSubview();"
+ class="text-link subviewkeynav"
+ flex="1">&contentBlocking.openBreakageReportView.label;</label>
</vbox>
</hbox>
<!-- Permissions Section -->
<hbox class="identity-popup-section"
when-connection="not-secure secure secure-ev secure-cert-user-overridden file extension">
<vbox id="identity-popup-permissions-content" flex="1" role="group"
aria-labelledby="identity-popup-permissions-headline">
@@ -228,10 +232,44 @@
<vbox id="identity-popup-more-info-footer" class="identity-popup-footer">
<!-- More Security Information -->
<button id="identity-popup-more-info"
label="&identity.moreInfoLinkText2;"
oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
</vbox>
</panelview>
+
+ <!-- Report Breakage SubView -->
+ <panelview id="identity-popup-breakageReportView"
+ title="&contentBlocking.breakageReportView.label;"
+ descriptionheightworkaround="true">
+ <vbox id="identity-popup-breakageReportView-heading">
+ <description>&contentBlocking.breakageReportView.description;</description>
+ <label id="identity-popup-breakageReportView-learn-more"
+ class="text-link">&contentBlocking.breakageReportView.learnMore;</label>
+ </vbox>
+ <vbox id="identity-popup-breakageReportView-body" class="panel-view-body-unscrollable">
+ <vbox class="identity-popup-breakageReportView-collection-section">
+ <label class="identity-popup-breakageReportView-collection-label">&contentBlocking.breakageReportView.collection.url.label;</label>
+ <label id="identity-popup-breakageReportView-collection-url"/>
+ </vbox>
+ <vbox class="identity-popup-breakageReportView-collection-section">
+ <label class="identity-popup-breakageReportView-collection-label">&contentBlocking.breakageReportView.collection.userAgent.label;</label>
+ <label id="identity-popup-breakageReportView-collection-userAgent"/>
+ </vbox>
+ <vbox class="identity-popup-breakageReportView-collection-section">
+ <label class="identity-popup-breakageReportView-collection-label">&contentBlocking.breakageReportView.collection.comments.label;</label>
+ <textbox multiline="true" id="identity-popup-breakageReportView-collection-comments"/>
+ </vbox>
+ </vbox>
+ <vbox id="identity-popup-breakageReportView-footer" class="identity-popup-footer">
+ <button id="identity-popup-breakageReportView-cancel"
+ label="&contentBlocking.breakageReportView.cancel.label;"
+ oncommand="ContentBlocking.backToMainView();"/>
+ <button id="identity-popup-breakageReportView-submit"
+ default="true"
+ label="&contentBlocking.breakageReportView.sendReport.label;"
+ oncommand="ContentBlocking.submitBreakageReport();"/>
+ </vbox>
+ </panelview>
</panelmultiview>
</panel>
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -946,16 +946,26 @@ you can use these alternative items. Oth
"Trackers [are] Blocked"-->
<!ENTITY contentBlocking.trackingProtection.blocked.label "Blocked">
<!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.add.label):
This is displayed as a link to preferences, where the user can add
this specific type of content blocking. When this text is shown
the type of content blocking is currently not enabled. -->
<!ENTITY contentBlocking.trackingProtection.add.label "Add Blocking…">
+<!ENTITY contentBlocking.openBreakageReportView.label "Report Problems">
+<!ENTITY contentBlocking.breakageReportView.label "Report Problems">
+<!ENTITY contentBlocking.breakageReportView.description "Content blocking can cause problems with some websites. When you report problems, you’ll help make &brandShortName; better for everyone. (This will send a URL as well as information about your privacy and content blocking settings to Mozilla.)">
+<!ENTITY contentBlocking.breakageReportView.learnMore "Learn More">
+<!ENTITY contentBlocking.breakageReportView.collection.url.label "URL">
+<!ENTITY contentBlocking.breakageReportView.collection.userAgent.label "&brandShortName; Version Number">
+<!ENTITY contentBlocking.breakageReportView.collection.comments.label "What problems did you have? (Optional)">
+<!ENTITY contentBlocking.breakageReportView.sendReport.label "Send Report">
+<!ENTITY contentBlocking.breakageReportView.cancel.label "Cancel">
+
<!ENTITY trackingProtection.title "Tracking Protection">
<!ENTITY trackingProtection.tooltip "Open Tracking Protection Preferences">
<!-- LOCALIZATION NOTE (trackingProtection.unblock3.label, trackingProtection.unblock3.accesskey):
The associated button with this label and accesskey is only shown when opening the control
center while looking at a site with trackers in NON-private browsing mode. -->
<!ENTITY trackingProtection.unblock4.label "Disable Blocking For This Site">
<!ENTITY trackingProtection.unblock4.accesskey "D">
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -142,16 +142,17 @@
}
.identity-popup-preferences-button > .toolbarbutton-text {
display: none;
}
/* CONTENT */
+#identity-popup-content-blocking-report-breakage,
#identity-popup-content-blocking-disabled-label,
.identity-popup-content-blocking-category-label,
.identity-popup-content-blocking-category-state-label,
.identity-popup-content-blocking-category-add-blocking,
.identity-popup-permission-label,
.identity-popup-permission-state-label,
.identity-popup-security-content > description,
#identity-popup-security-descriptions > description,
@@ -307,16 +308,63 @@ description#identity-popup-content-verif
#identity-popup-securityView-body > button {
margin-inline-start: 0;
margin-inline-end: 0;
}
/* CONTENT BLOCKING / TRACKING PROTECTION */
+#identity-popup-breakageReportView-footer {
+ display: flex;
+}
+
+#identity-popup-breakageReportView-footer > button {
+ flex: 1;
+}
+
+#identity-popup-breakageReportView-footer > button[default] {
+ color: white;
+ background-color: #0996f8;
+}
+
+#identity-popup-breakageReportView-footer > button[default]:hover {
+ background-color: #0675d3;
+}
+
+#identity-popup-breakageReportView-footer > button[default]:hover:active {
+ background-color: #0568ba;
+}
+
+#identity-popup-breakageReportView-heading,
+#identity-popup-breakageReportView-body {
+ padding: 16px;
+ font-size: 110%;
+}
+
+.identity-popup-breakageReportView-collection-label {
+ color: graytext;
+}
+
+#identity-popup-breakageReportView-collection-url {
+ word-wrap: break-word;
+}
+
+.identity-popup-breakageReportView-collection-section {
+ margin-bottom: 16px;
+}
+
+#identity-popup-breakageReportView-body {
+ border-top: 1px solid var(--panel-separator-color);
+}
+
+#identity-popup-breakageReportView-collection-comments {
+ height: 120px;
+}
+
#identity-popup-content-blocking-content {
background-image: url("chrome://browser/skin/controlcenter/tracking-protection.svg");
}
/* We can currently show either the old tracking protection-only UI, which has "Tracking Protection"
* as a label, or the new content blocking UI which has a different label and also a list of
* categories of blockers. This rule hides elements depending on which UI we want to show */
#identity-popup-content-blocking-content[contentBlockingUI] #tracking-protection-label,
@@ -413,16 +461,28 @@ description#identity-popup-content-verif
/* Content Blocking action button */
.tracking-protection-button {
margin: 1em 0 0;
display: none;
}
+#identity-popup-content-blocking-report-breakage {
+ margin-top: 6px;
+}
+
+/* Hide the "report breakage" button if TP is off or we have not detected any
+ * trackers (except if the user added an exception, in which case they might
+ * still (especially!) want to report the breakage). */
+#identity-popup-content-blocking-content:not([enabled]) #identity-popup-content-blocking-report-breakage,
+#identity-popup-content-blocking-content:not([detected]):not([hasException]) #identity-popup-content-blocking-report-breakage {
+ display: none;
+}
+
/* Show the right action buttons depending on content state */
/* Offer to temporarily add an exception in private mode. */
#main-window:not([privatebrowsingmode]) #identity-popup-content-blocking-content[enabled][detected]:not([hasException]) > #tracking-action-unblock,
/* Offer to permanently add an exception in normal mode. */
#main-window[privatebrowsingmode] #identity-popup-content-blocking-content[enabled][detected]:not([hasException]) > #tracking-action-unblock-private,
/* If there's an exception just offer to remove the exception again. */
#identity-popup-content-blocking-content[enabled][hasException] > #tracking-action-block {
display: -moz-box;