Bug 1501990 - Add a mode label to the Content Blocking section in the control center. r=johannh,flod
authorErica Wright <ewright@mozilla.com>
Mon, 26 Nov 2018 16:59:19 +0000
changeset 507220 f38d34679027acdcb303231cadbc7aef1849af53
parent 507219 d15f0ac561d9fc06518cf12851aaecf52eba485e
child 507241 a60b595747ade6cdad6b51906bc9a880f6276f19
child 507286 f61bf65fceaa591e9b3d6516457ab4039dd71a96
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh, flod
bugs1501990
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1501990 - Add a mode label to the Content Blocking section in the control center. r=johannh,flod Differential Revision: https://phabricator.services.mozilla.com/D12717
browser/base/content/browser-contentblocking.js
browser/base/content/test/trackingUI/browser.ini
browser/base/content/test/trackingUI/browser_trackingUI_categories.js
browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
browser/base/content/test/trackingUI/browser_trackingUI_state.js
browser/components/controlcenter/content/panel.inc.xul
browser/components/nsBrowserGlue.js
browser/locales/en-US/browser/preferences/preferences.ftl
browser/locales/en-US/chrome/browser/browser.dtd
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/shared/controlcenter/panel.inc.css
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -222,16 +222,17 @@ var ThirdPartyCookies = {
 
 var ContentBlocking = {
   // If the user ignores the doorhanger, we stop showing it after some time.
   MAX_INTROS: 20,
   PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
   PREF_REPORT_BREAKAGE_URL: "browser.contentblocking.reportBreakage.url",
   PREF_INTRO_COUNT_CB: "browser.contentblocking.introCount",
+  PREF_CB_CATEGORY: "browser.contentblocking.category",
   content: null,
   icon: null,
   activeTooltipText: null,
   disabledTooltipText: null,
 
   get prefIntroCount() {
     return this.PREF_INTRO_COUNT_CB;
   },
@@ -319,26 +320,52 @@ var ContentBlocking = {
 
     this.appMenuLabel.setAttribute("label", this.strings.appMenuTitle);
     this.appMenuLabel.setAttribute("tooltiptext", this.strings.appMenuTooltip);
 
     this.activeTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.activeTooltip");
     this.disabledTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip");
+    this.updateCBCategoryLabel = this.updateCBCategoryLabel.bind(this);
+    this.updateCBCategoryLabel();
+    Services.prefs.addObserver(this.PREF_CB_CATEGORY, this.updateCBCategoryLabel);
   },
 
   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_CB_CATEGORY, this.updateCBCategoryLabel);
+  },
+
+  updateCBCategoryLabel() {
+    if (!Services.prefs.prefHasUserValue(this.PREF_CB_CATEGORY)) {
+      // Fallback to not setting a label, it's preferable to not set a label than to set an incorrect one.
+      return;
+    }
+    let button = document.getElementById("tracking-protection-preferences-button");
+    let label;
+    let category = Services.prefs.getStringPref(this.PREF_CB_CATEGORY);
+    switch (category) {
+    case ("standard"):
+      label = gNavigatorBundle.getString("contentBlocking.category.standard");
+      break;
+    case ("strict"):
+      label = gNavigatorBundle.getString("contentBlocking.category.strict");
+      break;
+    case ("custom"):
+      label = gNavigatorBundle.getString("contentBlocking.category.custom");
+      break;
+    }
+    button.label = label;
   },
 
   hideIdentityPopupAndReload() {
     this.identityPopup.hidePopup();
     BrowserReload();
   },
 
   openPreferences(origin) {
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -7,16 +7,17 @@ support-files =
   cookieServer.sjs
   trackingAPI.js
   trackingPage.html
 
 [browser_trackingUI_3.js]
 [browser_trackingUI_animation.js]
 [browser_trackingUI_animation_2.js]
 [browser_trackingUI_appMenu.js]
+[browser_trackingUI_categories.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]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_categories.js
@@ -0,0 +1,42 @@
+const CAT_PREF = "browser.contentblocking.category";
+const TP_PREF = "privacy.trackingprotection.enabled";
+const TP_PB_PREF = "privacy.trackingprotection.pbmode.enabled";
+const TPC_PREF = "network.cookie.cookieBehavior";
+const TT_PREF = "urlclassifier.trackingTable";
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref(TP_PREF);
+  Services.prefs.clearUserPref(TP_PB_PREF);
+  Services.prefs.clearUserPref(TPC_PREF);
+  Services.prefs.clearUserPref(TT_PREF);
+  Services.prefs.clearUserPref(CAT_PREF);
+});
+
+add_task(async function testCategoryLabelsInControlPanel() {
+  await BrowserTestUtils.withNewTab("http://www.example.com", async function() {
+    let promisePanelOpen = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
+    gIdentityHandler._identityBox.click();
+    await promisePanelOpen;
+
+    let preferencesButton = document.getElementById("tracking-protection-preferences-button");
+    ok(preferencesButton.label, "The preferencesButton label exists");
+
+    Services.prefs.setStringPref(CAT_PREF, "strict");
+    await TestUtils.waitForCondition(() => preferencesButton.label ==
+      gNavigatorBundle.getString("contentBlocking.category.strict"));
+    is(preferencesButton.label, gNavigatorBundle.getString("contentBlocking.category.strict"),
+      "The preferencesButton label has been changed to strict");
+
+    Services.prefs.setStringPref(CAT_PREF, "standard");
+    await TestUtils.waitForCondition(() => preferencesButton.label ==
+      gNavigatorBundle.getString("contentBlocking.category.standard"));
+    is(preferencesButton.label, gNavigatorBundle.getString("contentBlocking.category.standard"),
+      "The preferencesButton label has been changed to standard");
+
+    Services.prefs.setStringPref(CAT_PREF, "custom");
+    await TestUtils.waitForCondition(() => preferencesButton.label ==
+      gNavigatorBundle.getString("contentBlocking.category.custom"));
+    is(preferencesButton.label, gNavigatorBundle.getString("contentBlocking.category.custom"),
+      "The preferencesButton label has been changed to custom");
+  });
+});
--- a/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
@@ -73,17 +73,16 @@ function testTrackingPageUnblocked() {
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
   ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
   is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
      gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
 
   ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
   ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
   ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-allowed"),
     "TP category item is showing the allowed label");
   ok(hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-blocked"),
--- a/browser/base/content/test/trackingUI/browser_trackingUI_state.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_state.js
@@ -60,17 +60,16 @@ function testBenignPage() {
 
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
   ok(!ContentBlocking.iconBox.hasAttribute("hasException"), "icon box shows no exception");
   ok(!ContentBlocking.iconBox.hasAttribute("tooltiptext"), "icon box has no tooltip");
 
   ok(BrowserTestUtils.is_hidden(ContentBlocking.iconBox), "icon box is hidden");
   ok(hidden("#tracking-action-block"), "blockButton is hidden");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  ok(hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is not visible");
 
   ok(!hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is visible");
   ok(hidden("#identity-popup-content-blocking-detected"), "blocking detected label is hidden");
   ok(hidden("#identity-popup-content-blocking-category-list"), "category list is hidden");
 }
 
 function testBenignPageWithException() {
   info("Non-tracking content must not be blocked");
@@ -81,17 +80,16 @@ function testBenignPageWithException() {
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
   ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
   is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
      gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
 
   ok(!BrowserTestUtils.is_hidden(ContentBlocking.iconBox), "icon box is not hidden");
   ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is visible");
   ok(hidden("#identity-popup-content-blocking-detected"), "blocking detected label is hidden");
   ok(hidden("#identity-popup-content-blocking-category-list"), "category list is hidden");
 }
 
 function areTrackersBlocked(isPrivateBrowsing) {
   let blockedByTP = Services.prefs.getBoolPref(isPrivateBrowsing ? TP_PB_PREF : TP_PREF);
@@ -170,17 +168,16 @@ function testTrackingPageUnblocked(block
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
   ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
   is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
      gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
 
   ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
   ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
 
   let cookiesBlocked = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
   if (cookiesBlocked) {
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -57,25 +57,16 @@
       <hbox id="tracking-protection-container"
             class="identity-popup-section"
             when-connection="not-secure secure secure-ev secure-cert-user-overridden extension">
         <vbox id="identity-popup-content-blocking-content" flex="1">
           <hbox align="start">
             <label id="content-blocking-label"
                    class="identity-popup-headline"
                    flex="1">&contentBlocking.title;</label>
-            <hbox id="identity-popup-content-blocking-disabled-label">
-              <image/>
-              <label id="identity-popup-content-blocking-disabled-label-exception"
-                     value="&contentBlocking.disabled.label;"
-                     tooltiptext="&contentBlocking.exception.tooltip;"/>
-              <label id="identity-popup-content-blocking-disabled-label-global"
-                     value="&contentBlocking.disabled.label;"
-                     tooltiptext="&contentBlocking.disabled.tooltip;"/>
-            </hbox>
             <toolbarbutton id="tracking-protection-preferences-button"
                            class="identity-popup-preferences-button subviewbutton"
                            oncommand="ContentBlocking.openPreferences('identityPopup-TP-preferencesButton'); gIdentityHandler.recordClick('cb_prefs_button');" />
           </hbox>
 
           <description id="identity-popup-content-blocking-detected"
                        crop="end">&contentBlocking.detected;</description>
           <description id="identity-popup-content-blocking-not-detected"
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -3041,17 +3041,17 @@ var ContentBlockingCategoriesPrefs = {
     } else if (this.prefsMatch("strict")) {
       Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "strict");
     } else {
       Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "custom");
     }
   },
 
   updateCBCategory() {
-    if (this.switchingCategory) {
+    if (this.switchingCategory || !Services.prefs.prefHasUserValue(this.PREF_CB_CATEGORY)) {
       return;
     }
     // Turn on switchingCategory flag, to ensure that when the individual prefs that change as a result
     // of the category change do not trigger yet another category change.
     this.switchingCategory = true;
     let value = Services.prefs.getStringPref(this.PREF_CB_CATEGORY);
     this.setPrefsToCategory(value);
     this.switchingCategory = false;
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -812,16 +812,18 @@ addressbar-suggestions-settings = Change
 ## Privacy Section - Content Blocking
 
 content-blocking-header = Content Blocking
 
 content-blocking-description = Block third-party content that tracks you around the web. Control how much of your online activity gets stored and shared between websites.
 
 content-blocking-learn-more = Learn more
 
+# The terminology used to refer to categories of Content Blocking is also used in chrome/browser/browser.properties and should be translated consistently.
+# "Standard" in this case is an adjective, meaning "default" or "normal".
 content-blocking-setting-standard =
   .label = Standard
   .accesskey = d
 content-blocking-setting-strict =
   .label = Strict
   .accesskey = r
 content-blocking-setting-custom =
   .label = Custom
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -961,19 +961,16 @@ you can use these alternative items. Oth
 <!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:">
 <!ENTITY getUserMedia.selectMicrophone.accesskey "M">
 <!ENTITY getUserMedia.audioCapture.label "Audio from the tab will be shared.">
 <!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
 
 <!ENTITY contentBlocking.title "Content Blocking">
 <!ENTITY contentBlocking.detected "Blockable content detected on this site.">
 <!ENTITY contentBlocking.notDetected "No blockable content detected on this page.">
-<!ENTITY contentBlocking.disabled.label "Disabled">
-<!ENTITY contentBlocking.disabled.tooltip "You have disabled Content Blocking.">
-<!ENTITY contentBlocking.exception.tooltip "You have disabled Content Blocking for this site.">
 
 <!ENTITY contentBlocking.trackingProtection3.label "Trackers">
 <!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.allowed.label):
      This label signals that this type of content blocking is turned
      OFF and is not blocking tracker content, so this is not
      a positive thing. It forms the end of the (imaginary) sentence
      "Trackers [are] Allowed"-->
 <!ENTITY contentBlocking.trackingProtection.allowed.label "Allowed">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -491,16 +491,25 @@ identity.notSecure.label=Not Secure
 identity.icon.tooltip=Show site information
 identity.extension.label=Extension (%S)
 identity.extension.tooltip=Loaded by extension: %S
 identity.showDetails.tooltip=Show connection details
 
 contentBlocking.title=Content Blocking
 contentBlocking.tooltip=Open Content Blocking Preferences
 
+# LOCALIZATION NOTE (contentBlocking.category.*):
+# The terminology used to refer to levels of Content Blocking is also used
+# in preferences and should be translated consistently.
+# LOCALIZATION NOTE (contentBlocking.category.standard):
+# "Standard" in this case is an adjective, meaning "default" or "normal"
+contentBlocking.category.standard=Standard
+contentBlocking.category.strict=Strict
+contentBlocking.category.custom=Custom
+
 # LOCALIZATION NOTE (contentBlocking.intro.title): %S is brandShortName.
 contentBlocking.intro.title=New in %S: Content Blocking
 # LOCALIZATION NOTE (contentBlocking.v1.intro.description): %S is brandShortName.
 contentBlocking.intro.v1.description=When you see the shield, %S is blocking parts of the page that can slow your browsing or track you online.
 contentBlocking.intro.v2.description=The privacy benefits of Tracking Protection are now just one part of content blocking. When you see the shield, content blocking is on.
 # LOCALIZATION NOTE (trackingProtection.intro.step1of3): Indicates that the intro panel is step one of three in a tour.
 trackingProtection.intro.step1of3=1 of 3
 trackingProtection.intro.nextButton.label=Next
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -133,37 +133,45 @@
 .identity-popup-expander:hover:active {
   background-color: var(--arrowpanel-dimmed-further);
   box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
 }
 
 /* PREFERENCES BUTTON */
 
 .identity-popup-preferences-button {
-  list-style-image: url(chrome://browser/skin/settings.svg);
+  min-width: 32px;
+  background: url(chrome://browser/skin/settings.svg) center right 8px no-repeat;
   padding: 5px 8px !important;
   margin-bottom: 2px !important;
 }
 
 .identity-popup-preferences-button > .toolbarbutton-text {
   display: none;
 }
 
+#tracking-protection-preferences-button > .toolbarbutton-text {
+  display: inline;
+  padding-inline-end: 25px;
+  padding-inline-start: 0px;
+  color: var(--panel-disabled-color);
+}
+
 /* CONTENT */
 
+#tracking-protection-preferences-button > .toolbarbutton-text,
 .identity-popup-footer,
 .tracking-protection-button,
 #identity-popup-trackersView-strict-info > label,
 .identity-popup-trackersView-list-item > label,
 #identity-popup-mainView-panel-header > label,
 #identity-popup-trackersView > .panel-header,
 #identity-popup-securityView > .panel-header,
 #identity-popup-breakageReportView > .panel-header,
 #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,
 #identity-popup-securityView-body > description,
@@ -473,50 +481,16 @@ description#identity-popup-content-verif
 }
 
 #identity-popup-trackersView-strict-info > label {
   overflow-wrap: break-word;
   /* Limit to full width - container margin - container padding - icon width - icon margin */
   max-width: calc(var(--identity-popup-width) - 12px - 20px - 16px - 10px);
 }
 
-/* Disabled label */
-
-#identity-popup-content-blocking-disabled-label {
-  padding: 2px 5px;
-  border-radius: 3px;
-  margin: 5px;
-  display: none;
-  color: #fff;
-  -moz-box-align: center;
-}
-
-#identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-disabled-label {
-  display: -moz-box;
-  background-color: #d7b600;
-  stroke: #d7b600;
-}
-
-#identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-disabled-label-global {
-  display: none;
-}
-
-#identity-popup-content-blocking-disabled-label > label {
-  margin: 0;
-}
-
-#identity-popup-content-blocking-disabled-label > image {
-  list-style-image: url(chrome://browser/skin/controlcenter/warning.svg);
-  fill: currentColor;
-  -moz-context-properties: fill, stroke;
-  margin-inline-end: 4px;
-  height: 13px;
-  width: 13px;
-}
-
 /* Content Blocking categories */
 
 #identity-popup-content-blocking-category-list {
   margin-top: 10px;
 }
 
 /* Don't show the categories when no trackers were detected. */
 #identity-popup-content-blocking-content:not([detected]) > #identity-popup-content-blocking-category-list {