diff --git a/browser/base/content/browser-contentblocking.js b/browser/base/content/browser-contentblocking.js
index 3450f07bed31..678271c6e914 100644
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -15,6 +15,10 @@ var FastBlock = {
XPCOMUtils.defineLazyPreferenceGetter(this, "enabled", this.PREF_ENABLED, false);
XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
},
+
+ isBlockerActivated(state) {
+ return state & Ci.nsIWebProgressListener.STATE_BLOCKED_SLOW_TRACKING_CONTENT;
+ },
};
var TrackingProtection = {
@@ -128,6 +132,10 @@ var TrackingProtection = {
}
}
},
+
+ isBlockerActivated(state) {
+ return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
+ },
};
var ThirdPartyCookies = {
@@ -154,6 +162,11 @@ var ThirdPartyCookies = {
get enabled() {
return this.PREF_ENABLED_VALUES.includes(this.behaviorPref);
},
+
+ isBlockerActivated(state) {
+ return (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER) != 0 ||
+ (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN) != 0;
+ },
};
@@ -434,23 +447,21 @@ var ContentBlocking = {
this.iconBox.removeAttribute("animate");
}
- let isBlocking = state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
- let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
- let detected = isBlocking || isAllowing;
-
- let anyBlockerEnabled = false;
+ let anyBlockerActivated = false;
for (let blocker of this.blockers) {
blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
blocker.categoryItem.hidden = !blocker.visible;
- anyBlockerEnabled = anyBlockerEnabled || blocker.enabled;
+ anyBlockerActivated = anyBlockerActivated || blocker.isBlockerActivated(state);
}
- // We consider the shield state "active" when any kind of blocking-related
- // activity occurs on the page (blocking or allowing) and at least one blocker
- // is enabled.
+ // We consider the shield state "active" when some kind of blocking activity
+ // occurs on the page. Note that merely allowing the loading of content that
+ // we could have blocked does not trigger the appearance of the shield.
// This state will be overriden later if there's an exception set for this site.
- let active = this.enabled && detected && anyBlockerEnabled;
+ let active = this.enabled && anyBlockerActivated;
+ let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
+ let detected = anyBlockerActivated || isAllowing;
let isBrowserPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
diff --git a/browser/base/content/test/trackingUI/browser.ini b/browser/base/content/test/trackingUI/browser.ini
index ba45e89b527c..5bc8d8a6d977 100644
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -3,6 +3,8 @@ tags = trackingprotection
support-files =
head.js
benignPage.html
+ cookiePage.html
+ cookieServer.sjs
trackingPage.html
[browser_trackingUI_3.js]
diff --git a/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js b/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
index 8f4adbaf20d7..5e281c263b32 100644
--- a/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
@@ -75,7 +75,7 @@ function testTrackingPageUnblocked() {
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
- ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
+ 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");
diff --git a/browser/base/content/test/trackingUI/browser_trackingUI_state.js b/browser/base/content/test/trackingUI/browser_trackingUI_state.js
index ef4da753883c..5110aedd57b1 100644
--- a/browser/base/content/test/trackingUI/browser_trackingUI_state.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_state.js
@@ -18,18 +18,29 @@ const CB_PREF = "browser.contentblocking.enabled";
const CB_UI_PREF = "browser.contentblocking.ui.enabled";
const TP_PREF = "privacy.trackingprotection.enabled";
const TP_PB_PREF = "privacy.trackingprotection.pbmode.enabled";
+const FB_PREF = "browser.fastblock.enabled";
+const FB_TIMEOUT_PREF = "browser.fastblock.timeout";
+const TPC_PREF = "network.cookie.cookieBehavior";
const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
+const COOKIE_PAGE = "http://not-tracking.example.com/browser/browser/base/content/test/trackingUI/cookiePage.html";
var ContentBlocking = null;
+var FastBlock = null;
var TrackingProtection = null;
+var ThirdPartyCookies = null;
var tabbrowser = null;
+var gTrackingPageURL = TRACKING_PAGE;
registerCleanupFunction(function() {
- TrackingProtection = ContentBlocking = tabbrowser = null;
+ TrackingProtection = ContentBlocking = FastBlock =
+ ThirdPartyCookies = tabbrowser = null;
UrlClassifierTestUtils.cleanupTestTrackers();
Services.prefs.clearUserPref(TP_PREF);
Services.prefs.clearUserPref(TP_PB_PREF);
Services.prefs.clearUserPref(CB_PREF);
+ Services.prefs.clearUserPref(FB_PREF);
+ Services.prefs.clearUserPref(FB_TIMEOUT_PREF);
+ Services.prefs.clearUserPref(TPC_PREF);
});
// This is a special version of "hidden" that doesn't check for item
@@ -98,25 +109,47 @@ function testBenignPageWithException() {
}
}
+function areTrackersBlocked(isPrivateBrowsing) {
+ let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
+ let blockedByTP = cbEnabled &&
+ Services.prefs.getBoolPref(isPrivateBrowsing ? TP_PB_PREF : TP_PREF);
+ let blockedByFB = cbEnabled &&
+ Services.prefs.getBoolPref(FB_PREF) &&
+ // The timeout pref is only checked for completeness,
+ // checking it is technically unneeded for this test.
+ Services.prefs.getIntPref(FB_TIMEOUT_PREF) == 0;
+ let blockedByTPC = cbEnabled &&
+ Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
+ return blockedByTP || blockedByFB || blockedByTPC;
+}
+
function testTrackingPage(window) {
info("Tracking content must be blocked");
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(!ContentBlocking.content.hasAttribute("hasException"), "content shows no exception");
- ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
- ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
+ let isPrivateBrowsing = PrivateBrowsingUtils.isWindowPrivate(window);
+ let blockedByTP = areTrackersBlocked(isPrivateBrowsing);
+ is(BrowserTestUtils.is_visible(ContentBlocking.iconBox), blockedByTP,
+ "icon box is" + (blockedByTP ? "" : " not") + " visible");
+ is(ContentBlocking.iconBox.hasAttribute("active"), blockedByTP,
+ "shield is" + (blockedByTP ? "" : " not") + " active");
ok(!ContentBlocking.iconBox.hasAttribute("hasException"), "icon box shows no exception");
is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
- gNavigatorBundle.getString("trackingProtection.icon.activeTooltip"), "correct tooltip");
+ blockedByTP ? gNavigatorBundle.getString("trackingProtection.icon.activeTooltip") : "",
+ "correct tooltip");
ok(hidden("#tracking-action-block"), "blockButton is hidden");
+ let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
- ok(!hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is visible");
+ is(hidden("#tracking-action-unblock-private"), !cbEnabled,
+ "unblockButtonPrivate is" + (cbEnabled ? "" : " not") + " visible");
} else {
ok(!hidden("#tracking-action-unblock"), "unblockButton is visible");
- ok(hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is hidden");
+ is(hidden("#tracking-action-unblock-private"), cbEnabled,
+ "unblockButtonPrivate is" + (cbEnabled ? "" : " not") + " hidden");
}
ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
@@ -124,25 +157,37 @@ function testTrackingPage(window) {
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
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-category-add-blocking"),
- "TP category item is not showing add blocking");
- ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
- "TP category item is set to blocked");
+ let category;
+ if (Services.prefs.getBoolPref(FB_PREF)) {
+ category = "#identity-popup-content-blocking-category-fastblock";
+ } else {
+ category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
+ "#identity-popup-content-blocking-category-3rdpartycookies" :
+ "#identity-popup-content-blocking-category-tracking-protection";
+ }
+ is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
+ "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
+ is(hidden(category + " > .identity-popup-content-blocking-category-state-label"), !blockedByTP,
+ "Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
}
}
-function testTrackingPageUnblocked() {
+function testTrackingPageUnblocked(blockedByTP) {
info("Tracking content must be white-listed and not blocked");
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
- ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
- ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
+ let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
+ ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
+ is(ContentBlocking.iconBox.hasAttribute("hasException"), cbEnabled,
+ "shield" + (cbEnabled ? " shows" : " doesn't show") + " 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");
+ is(BrowserTestUtils.is_visible(ContentBlocking.iconBox), cbEnabled,
+ "icon box is" + (cbEnabled ? "" : " not") + " visible");
+ is(hidden("#tracking-action-block"), !cbEnabled,
+ "blockButton is" + (cbEnabled ? " not" : "") + " visible");
ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
@@ -151,8 +196,17 @@ function testTrackingPageUnblocked() {
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
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-category-add-blocking"),
- "TP category item is not showing add blocking");
+ let category;
+ if (Services.prefs.getBoolPref(FB_PREF)) {
+ category = "#identity-popup-content-blocking-category-fastblock";
+ } else {
+ category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
+ "#identity-popup-content-blocking-category-3rdpartycookies" :
+ "#identity-popup-content-blocking-category-tracking-protection";
+ }
+ is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
+ "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
+ // Always hidden no matter if blockedByTP or not, since we have an exception.
ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
"TP category item is not set to blocked");
}
@@ -210,14 +264,15 @@ async function testContentBlockingEnabled(tab) {
}
info("Load a test page containing tracking elements");
- await promiseTabLoadEvent(tab, TRACKING_PAGE);
+ await promiseTabLoadEvent(tab, gTrackingPageURL);
testTrackingPage(tab.ownerGlobal);
info("Disable CB for the page (which reloads the page)");
let tabReloadPromise = promiseTabLoadEvent(tab);
clickButton("#tracking-action-unblock");
await tabReloadPromise;
- testTrackingPageUnblocked();
+ let blockedByTP = areTrackersBlocked(isPrivateBrowsing);
+ testTrackingPageUnblocked(blockedByTP);
info("Re-enable TP for the page (which reloads the page)");
tabReloadPromise = promiseTabLoadEvent(tab);
@@ -252,7 +307,7 @@ async function testContentBlockingDisabled(tab) {
}
info("Load a test page containing tracking elements");
- await promiseTabLoadEvent(tab, TRACKING_PAGE);
+ await promiseTabLoadEvent(tab, gTrackingPageURL);
testTrackingPageWithCBDisabled();
}
@@ -269,6 +324,20 @@ add_task(async function testNormalBrowsing() {
is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PREF),
"TP.enabled is based on the original pref value");
+ Services.prefs.setBoolPref(FB_PREF, false);
+
+ await testContentBlockingEnabled(tab);
+
+ if (Services.prefs.getBoolPref(CB_UI_PREF)) {
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+ } else {
+ Services.prefs.setBoolPref(TP_PREF, false);
+ ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
+ }
+
+ await testContentBlockingDisabled(tab);
+
Services.prefs.setBoolPref(TP_PREF, true);
ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
@@ -287,6 +356,8 @@ add_task(async function testNormalBrowsing() {
await testContentBlockingDisabled(tab);
gBrowser.removeCurrentTab();
+
+ Services.prefs.clearUserPref(FB_PREF);
});
add_task(async function testPrivateBrowsing() {
@@ -297,6 +368,8 @@ add_task(async function testPrivateBrowsing() {
// Set the normal mode pref to false to check the pbmode pref.
Services.prefs.setBoolPref(TP_PREF, false);
+ Services.prefs.setBoolPref(FB_PREF, false);
+
ContentBlocking = tabbrowser.ownerGlobal.ContentBlocking;
ok(ContentBlocking, "CB is attached to the private window");
TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
@@ -304,6 +377,18 @@ add_task(async function testPrivateBrowsing() {
is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PB_PREF),
"TP.enabled is based on the pb pref value");
+ await testContentBlockingEnabled(tab);
+
+ if (Services.prefs.getBoolPref(CB_UI_PREF)) {
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+ } else {
+ Services.prefs.setBoolPref(TP_PREF, false);
+ ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
+ }
+
+ await testContentBlockingDisabled(tab);
+
Services.prefs.setBoolPref(TP_PB_PREF, true);
ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
@@ -322,4 +407,105 @@ add_task(async function testPrivateBrowsing() {
await testContentBlockingDisabled(tab);
privateWin.close();
+
+ Services.prefs.clearUserPref(FB_PREF);
+});
+
+add_task(async function testFastBlock() {
+ if (!SpecialPowers.getBoolPref(CB_UI_PREF)) {
+ info("The FastBlock test is disabled when the Content Blocking UI is disabled");
+ return;
+ }
+
+ await UrlClassifierTestUtils.addTestTrackers();
+
+ tabbrowser = gBrowser;
+ let tab = tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser);
+
+ Services.prefs.setBoolPref(FB_PREF, false);
+
+ ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
+ ok(ContentBlocking, "CB is attached to the browser window");
+ FastBlock = gBrowser.ownerGlobal.FastBlock;
+ ok(FastBlock, "TP is attached to the browser window");
+ is(FastBlock.enabled, Services.prefs.getBoolPref(FB_PREF),
+ "FB.enabled is based on the original pref value");
+ Services.prefs.setBoolPref(CB_PREF, true);
+ ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
+
+ await testContentBlockingEnabled(tab);
+
+ ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+
+ await testContentBlockingDisabled(tab);
+
+ Services.prefs.setBoolPref(FB_PREF, true);
+ Services.prefs.setIntPref(FB_TIMEOUT_PREF, 0);
+ ok(FastBlock.enabled, "FB is enabled after setting the pref");
+ Services.prefs.setBoolPref(CB_PREF, true);
+ ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
+
+ await testContentBlockingEnabled(tab);
+
+ ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+
+ await testContentBlockingDisabled(tab);
+
+ Services.prefs.clearUserPref(FB_PREF);
+ Services.prefs.clearUserPref(FB_TIMEOUT_PREF);
+ gBrowser.removeCurrentTab();
+});
+
+add_task(async function testThirdPartyCookies() {
+ if (!SpecialPowers.getBoolPref(CB_UI_PREF)) {
+ info("The ThirdPartyCookies test is disabled when the Content Blocking UI is disabled");
+ return;
+ }
+
+ await UrlClassifierTestUtils.addTestTrackers();
+ gTrackingPageURL = COOKIE_PAGE;
+
+ Services.prefs.setBoolPref(FB_PREF, false);
+
+ tabbrowser = gBrowser;
+ let tab = tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser);
+
+ ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
+ ok(ContentBlocking, "CB is attached to the browser window");
+ ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
+ ok(ThirdPartyCookies, "TP is attached to the browser window");
+ is(ThirdPartyCookies.enabled,
+ Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
+ "TPC.enabled is based on the original pref value");
+ Services.prefs.setBoolPref(CB_PREF, true);
+ ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
+
+ await testContentBlockingEnabled(tab);
+
+ ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+
+ await testContentBlockingDisabled(tab);
+
+ Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
+ ok(ThirdPartyCookies.enabled, "TPC is enabled after setting the pref");
+ Services.prefs.setBoolPref(CB_PREF, true);
+ ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
+
+ await testContentBlockingEnabled(tab);
+
+ ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
+ Services.prefs.setBoolPref(CB_PREF, false);
+ ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
+
+ await testContentBlockingDisabled(tab);
+
+ Services.prefs.clearUserPref(FB_PREF);
+ Services.prefs.clearUserPref(TPC_PREF);
+ gBrowser.removeCurrentTab();
});
diff --git a/browser/base/content/test/trackingUI/cookiePage.html b/browser/base/content/test/trackingUI/cookiePage.html
new file mode 100644
index 000000000000..4df463031cb0
--- /dev/null
+++ b/browser/base/content/test/trackingUI/cookiePage.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/base/content/test/trackingUI/cookieServer.sjs b/browser/base/content/test/trackingUI/cookieServer.sjs
new file mode 100644
index 000000000000..4c84df3922e3
--- /dev/null
+++ b/browser/base/content/test/trackingUI/cookieServer.sjs
@@ -0,0 +1,9 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, 200);
+ response.setHeader("Set-Cookie", "foopy=1");
+ response.write("cookie served");
+}
diff --git a/browser/components/preferences/in-content/privacy.xul b/browser/components/preferences/in-content/privacy.xul
index 3db43e9f5eb9..bd3cb49bd759 100644
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -370,7 +370,6 @@
data-l10n-id="content-blocking-tracking-protection-option-always"
flex="1" />
-