forked from mirrors/gecko-dev
Depends on D9519 Differential Revision: https://phabricator.services.mozilla.com/D9520 --HG-- extra : moz-landing-system : lando
599 lines
23 KiB
JavaScript
599 lines
23 KiB
JavaScript
/* 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/. */
|
|
|
|
var FastBlock = {
|
|
reportBreakageLabel: "fastblock",
|
|
telemetryIdentifier: "fb",
|
|
PREF_ENABLED: "browser.fastblock.enabled",
|
|
PREF_UI_ENABLED: "browser.contentblocking.fastblock.control-center.ui.enabled",
|
|
|
|
get categoryItem() {
|
|
delete this.categoryItem;
|
|
return this.categoryItem = document.getElementById("identity-popup-content-blocking-category-fastblock");
|
|
},
|
|
|
|
init() {
|
|
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 = {
|
|
reportBreakageLabel: "trackingprotection",
|
|
telemetryIdentifier: "tp",
|
|
PREF_ENABLED_GLOBALLY: "privacy.trackingprotection.enabled",
|
|
PREF_ENABLED_IN_PRIVATE_WINDOWS: "privacy.trackingprotection.pbmode.enabled",
|
|
PREF_UI_ENABLED: "browser.contentblocking.trackingprotection.control-center.ui.enabled",
|
|
enabledGlobally: false,
|
|
enabledInPrivateWindows: false,
|
|
|
|
get categoryItem() {
|
|
delete this.categoryItem;
|
|
return this.categoryItem =
|
|
document.getElementById("identity-popup-content-blocking-category-tracking-protection");
|
|
},
|
|
|
|
init() {
|
|
this.updateEnabled();
|
|
|
|
Services.prefs.addObserver(this.PREF_ENABLED_GLOBALLY, this);
|
|
Services.prefs.addObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this);
|
|
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
|
|
},
|
|
|
|
uninit() {
|
|
Services.prefs.removeObserver(this.PREF_ENABLED_GLOBALLY, this);
|
|
Services.prefs.removeObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this);
|
|
},
|
|
|
|
observe() {
|
|
this.updateEnabled();
|
|
},
|
|
|
|
get enabled() {
|
|
return this.enabledGlobally ||
|
|
(this.enabledInPrivateWindows &&
|
|
PrivateBrowsingUtils.isWindowPrivate(window));
|
|
},
|
|
|
|
updateEnabled() {
|
|
this.enabledGlobally =
|
|
Services.prefs.getBoolPref(this.PREF_ENABLED_GLOBALLY);
|
|
this.enabledInPrivateWindows =
|
|
Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
|
|
},
|
|
|
|
isBlockerActivated(state) {
|
|
return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
|
|
},
|
|
};
|
|
|
|
var ThirdPartyCookies = {
|
|
telemetryIdentifier: "cr",
|
|
PREF_ENABLED: "network.cookie.cookieBehavior",
|
|
PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.rejecttrackers.reportBreakage.enabled",
|
|
PREF_ENABLED_VALUES: [
|
|
// These values match the ones exposed under the Content Blocking section
|
|
// of the Preferences UI.
|
|
Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN, // Block all third-party cookies
|
|
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER, // Block third-party cookies from trackers
|
|
],
|
|
PREF_UI_ENABLED: "browser.contentblocking.rejecttrackers.control-center.ui.enabled",
|
|
|
|
get categoryItem() {
|
|
delete this.categoryItem;
|
|
return this.categoryItem =
|
|
document.getElementById("identity-popup-content-blocking-category-3rdpartycookies");
|
|
},
|
|
|
|
get reportBreakageLabel() {
|
|
switch (this.behaviorPref) {
|
|
case Ci.nsICookieService.BEHAVIOR_ACCEPT:
|
|
return "nocookiesblocked";
|
|
case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
|
|
return "allthirdpartycookiesblocked";
|
|
case Ci.nsICookieService.BEHAVIOR_REJECT:
|
|
return "allcookiesblocked";
|
|
case Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN:
|
|
return "cookiesfromunvisitedsitesblocked";
|
|
default:
|
|
Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
|
|
// fall through
|
|
case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
|
|
return "cookierestrictions";
|
|
}
|
|
},
|
|
|
|
get categoryLabelDefault() {
|
|
delete this.categoryLabelDefault;
|
|
return this.categoryLabelDefault =
|
|
document.getElementById("identity-popup-content-blocking-category-label-default");
|
|
},
|
|
|
|
get categoryLabelTrackers() {
|
|
delete this.categoryLabelTrackers;
|
|
return this.categoryLabelTrackers =
|
|
document.getElementById("identity-popup-content-blocking-category-label-trackers");
|
|
},
|
|
|
|
updateCategoryLabel() {
|
|
let rejectTrackers = this.behaviorPref == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
|
|
this.categoryLabelDefault.hidden = rejectTrackers;
|
|
this.categoryLabelTrackers.hidden = !rejectTrackers;
|
|
},
|
|
|
|
init() {
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "behaviorPref", this.PREF_ENABLED,
|
|
Ci.nsICookieService.BEHAVIOR_ACCEPT, this.updateCategoryLabel.bind(this));
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
|
|
this.PREF_REPORT_BREAKAGE_ENABLED, false);
|
|
this.updateCategoryLabel();
|
|
},
|
|
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;
|
|
},
|
|
};
|
|
|
|
|
|
var ContentBlocking = {
|
|
// If the user ignores the doorhanger, we stop showing it after some time.
|
|
MAX_INTROS: 20,
|
|
PREF_ENABLED: "browser.contentblocking.enabled",
|
|
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_GLOBAL_TOGGLE: "browser.contentblocking.global-toggle.enabled",
|
|
content: null,
|
|
icon: null,
|
|
activeTooltipText: null,
|
|
disabledTooltipText: null,
|
|
|
|
get prefIntroCount() {
|
|
return this.PREF_INTRO_COUNT_CB;
|
|
},
|
|
|
|
get appMenuLabel() {
|
|
delete this.appMenuLabel;
|
|
return this.appMenuLabel = document.getElementById("appMenu-tp-label");
|
|
},
|
|
|
|
get appMenuButton() {
|
|
delete this.appMenuButton;
|
|
return this.appMenuButton = document.getElementById("appMenu-tp-toggle");
|
|
},
|
|
|
|
get appMenuVerticalSeparator() {
|
|
delete this.appMenuVerticalSeparator;
|
|
return this.appMenuVerticalSeparator = document.getElementById("appMenu-tp-vertical-separator");
|
|
},
|
|
|
|
strings: {
|
|
get enableTooltip() {
|
|
delete this.enableTooltip;
|
|
return this.enableTooltip =
|
|
gNavigatorBundle.getString("contentBlocking.toggle.enable.tooltip");
|
|
},
|
|
|
|
get disableTooltip() {
|
|
delete this.disableTooltip;
|
|
return this.disableTooltip =
|
|
gNavigatorBundle.getString("contentBlocking.toggle.disable.tooltip");
|
|
},
|
|
|
|
get appMenuTitle() {
|
|
delete this.appMenuTitle;
|
|
return this.appMenuTitle =
|
|
gNavigatorBundle.getString("contentBlocking.title");
|
|
},
|
|
|
|
get appMenuTooltip() {
|
|
delete this.appMenuTooltip;
|
|
return this.appMenuTooltip =
|
|
gNavigatorBundle.getString("contentBlocking.tooltip");
|
|
},
|
|
},
|
|
|
|
// A list of blockers that will be displayed in the categories list
|
|
// when blockable content is detected. A blocker must be an object
|
|
// with at least the following two properties:
|
|
// - enabled: Whether the blocker is currently turned on.
|
|
// - categoryItem: The DOM item that represents the entry in the category list.
|
|
//
|
|
// It may also contain an init() and uninit() function, which will be called
|
|
// on ContentBlocking.init() and ContentBlocking.uninit().
|
|
blockers: [FastBlock, TrackingProtection, ThirdPartyCookies],
|
|
|
|
get _baseURIForChannelClassifier() {
|
|
// Convert document URI into the format used by
|
|
// nsChannelClassifier::ShouldEnableTrackingProtection.
|
|
// Any scheme turned into https is correct.
|
|
try {
|
|
return Services.io.newURI("https://" + gBrowser.selectedBrowser.currentURI.hostPort);
|
|
} catch (e) {
|
|
// Getting the hostPort for about: and file: URIs fails, but TP doesn't work with
|
|
// these URIs anyway, so just return null here.
|
|
return null;
|
|
}
|
|
},
|
|
|
|
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.reportBreakageLearnMore = $("#identity-popup-breakageReportView-learn-more");
|
|
|
|
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
|
|
this.reportBreakageLearnMore.href = baseURL + "blocking-breakage";
|
|
|
|
this.updateGlobalToggleVisibility = () => {
|
|
if (Services.prefs.getBoolPref(this.PREF_GLOBAL_TOGGLE, true)) {
|
|
this.appMenuButton.removeAttribute("hidden");
|
|
this.appMenuVerticalSeparator.removeAttribute("hidden");
|
|
} else {
|
|
this.appMenuButton.setAttribute("hidden", "true");
|
|
this.appMenuVerticalSeparator.setAttribute("hidden", "true");
|
|
}
|
|
};
|
|
|
|
this.updateGlobalToggleVisibility();
|
|
|
|
Services.prefs.addObserver(this.PREF_GLOBAL_TOGGLE, this.updateGlobalToggleVisibility);
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
this.updateAnimationsEnabled();
|
|
|
|
Services.prefs.addObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
|
|
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "contentBlockingEnabled", this.PREF_ENABLED, false,
|
|
this.updateEnabled.bind(this));
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
|
|
this.PREF_REPORT_BREAKAGE_ENABLED, false);
|
|
|
|
this.updateEnabled();
|
|
|
|
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");
|
|
},
|
|
|
|
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_GLOBAL_TOGGLE, this.updateGlobalToggleVisibility);
|
|
},
|
|
|
|
get enabled() {
|
|
return this.contentBlockingEnabled;
|
|
},
|
|
|
|
updateEnabled() {
|
|
this.content.toggleAttribute("enabled", this.enabled);
|
|
|
|
this.appMenuButton.setAttribute("tooltiptext", this.enabled ?
|
|
this.strings.disableTooltip : this.strings.enableTooltip);
|
|
this.appMenuButton.setAttribute("enabled", this.enabled);
|
|
this.appMenuButton.setAttribute("aria-pressed", this.enabled);
|
|
|
|
// The enabled state of blockers may also change since it depends on this.enabled.
|
|
for (let blocker of this.blockers) {
|
|
blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
|
|
}
|
|
},
|
|
|
|
onGlobalToggleCommand() {
|
|
Services.prefs.setBoolPref(this.PREF_ENABLED, !this.enabled);
|
|
},
|
|
|
|
hideIdentityPopupAndReload() {
|
|
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: ${navigator.userAgent}\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 += `${TrackingProtection.PREF_UI_ENABLED}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_UI_ENABLED)}\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 += `${ThirdPartyCookies.PREF_UI_ENABLED}: ${Services.prefs.getBoolPref(ThirdPartyCookies.PREF_UI_ENABLED)}\n`;
|
|
body += `${ThirdPartyCookies.PREF_ENABLED}: ${Services.prefs.getIntPref(ThirdPartyCookies.PREF_ENABLED)}\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 += `${FastBlock.PREF_UI_ENABLED}: ${Services.prefs.getBoolPref(FastBlock.PREF_UI_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);
|
|
|
|
let activatedBlockers = [];
|
|
for (let blocker of this.blockers) {
|
|
if (blocker.activated) {
|
|
activatedBlockers.push(blocker.reportBreakageLabel);
|
|
}
|
|
}
|
|
|
|
if (activatedBlockers.length) {
|
|
formData.set("labels", activatedBlockers.join(","));
|
|
}
|
|
|
|
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.identityPopupMultiView.showSubView("identity-popup-breakageReportView");
|
|
},
|
|
|
|
shieldHistogramAdd(value) {
|
|
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
|
|
return;
|
|
}
|
|
Services.telemetry.getHistogramById("TRACKING_PROTECTION_SHIELD").add(value);
|
|
},
|
|
|
|
onSecurityChange(oldState, state, webProgress, isSimulated,
|
|
contentBlockingLogJSON) {
|
|
let baseURI = this._baseURIForChannelClassifier;
|
|
|
|
// Don't deal with about:, file: etc.
|
|
if (!baseURI) {
|
|
this.iconBox.removeAttribute("animate");
|
|
this.iconBox.removeAttribute("active");
|
|
this.iconBox.removeAttribute("hasException");
|
|
return;
|
|
}
|
|
|
|
// The user might have navigated before the shield animation
|
|
// finished. In this case, reset the animation to be able to
|
|
// play it in full again and avoid choppiness.
|
|
if (webProgress.isTopLevel) {
|
|
this.iconBox.removeAttribute("animate");
|
|
}
|
|
|
|
let anyBlockerActivated = false;
|
|
|
|
for (let blocker of this.blockers) {
|
|
// Store data on whether the blocker is activated in the current document for
|
|
// reporting it using the "report breakage" dialog. Under normal circumstances this
|
|
// dialog should only be able to open in the currently selected tab and onSecurityChange
|
|
// runs on tab switch, so we can avoid associating the data with the document directly.
|
|
blocker.activated = blocker.isBlockerActivated(state);
|
|
blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
|
|
blocker.categoryItem.hidden = !blocker.visible;
|
|
anyBlockerActivated = anyBlockerActivated || blocker.activated;
|
|
}
|
|
|
|
// 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 && anyBlockerActivated;
|
|
let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
|
|
let detected = anyBlockerActivated || isAllowing;
|
|
|
|
let isBrowserPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
|
|
|
|
// Check whether the user has added an exception for this site.
|
|
let type = isBrowserPrivate ? "trackingprotection-pb" : "trackingprotection";
|
|
let hasException = Services.perms.testExactPermission(baseURI, type) ==
|
|
Services.perms.ALLOW_ACTION;
|
|
|
|
this.content.toggleAttribute("detected", detected);
|
|
this.content.toggleAttribute("hasException", hasException);
|
|
this.content.toggleAttribute("active", active);
|
|
|
|
this.iconBox.toggleAttribute("active", active);
|
|
this.iconBox.toggleAttribute("hasException", this.enabled && hasException);
|
|
|
|
// For release (due to the large volume) we only want to receive reports
|
|
// for breakage that is directly related to third party cookie blocking.
|
|
if (this.reportBreakageEnabled ||
|
|
(ThirdPartyCookies.reportBreakageEnabled &&
|
|
ThirdPartyCookies.activated &&
|
|
!FastBlock.activated &&
|
|
!TrackingProtection.activated)) {
|
|
this.reportBreakageButton.removeAttribute("hidden");
|
|
} else {
|
|
this.reportBreakageButton.setAttribute("hidden", "true");
|
|
}
|
|
|
|
if (isSimulated) {
|
|
this.iconBox.removeAttribute("animate");
|
|
} else if (active && webProgress.isTopLevel) {
|
|
this.iconBox.setAttribute("animate", "true");
|
|
|
|
if (!isBrowserPrivate) {
|
|
let introCount = Services.prefs.getIntPref(this.prefIntroCount);
|
|
if (introCount < this.MAX_INTROS) {
|
|
Services.prefs.setIntPref(this.prefIntroCount, ++introCount);
|
|
Services.prefs.savePrefFile(null);
|
|
this.showIntroPanel();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasException) {
|
|
this.iconBox.setAttribute("tooltiptext", this.disabledTooltipText);
|
|
this.shieldHistogramAdd(1);
|
|
} else if (active) {
|
|
this.iconBox.setAttribute("tooltiptext", this.activeTooltipText);
|
|
this.shieldHistogramAdd(2);
|
|
} else {
|
|
this.iconBox.removeAttribute("tooltiptext");
|
|
this.shieldHistogramAdd(0);
|
|
}
|
|
},
|
|
|
|
disableForCurrentPage() {
|
|
let baseURI = this._baseURIForChannelClassifier;
|
|
|
|
// Add the current host in the 'trackingprotection' consumer of
|
|
// the permission manager using a normalized URI. This effectively
|
|
// places this host on the tracking protection allowlist.
|
|
if (PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser)) {
|
|
PrivateBrowsingUtils.addToTrackingAllowlist(baseURI);
|
|
} else {
|
|
Services.perms.add(baseURI,
|
|
"trackingprotection", Services.perms.ALLOW_ACTION);
|
|
}
|
|
|
|
this.hideIdentityPopupAndReload();
|
|
},
|
|
|
|
enableForCurrentPage() {
|
|
// Remove the current host from the 'trackingprotection' consumer
|
|
// of the permission manager. This effectively removes this host
|
|
// from the tracking protection allowlist.
|
|
let baseURI = this._baseURIForChannelClassifier;
|
|
|
|
if (PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser)) {
|
|
PrivateBrowsingUtils.removeFromTrackingAllowlist(baseURI);
|
|
} else {
|
|
Services.perms.remove(baseURI, "trackingprotection");
|
|
}
|
|
|
|
this.hideIdentityPopupAndReload();
|
|
},
|
|
|
|
dontShowIntroPanelAgain() {
|
|
if (!PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser)) {
|
|
Services.prefs.setIntPref(this.prefIntroCount, this.MAX_INTROS);
|
|
Services.prefs.savePrefFile(null);
|
|
}
|
|
},
|
|
|
|
async showIntroPanel() {
|
|
let brandBundle = document.getElementById("bundle_brand");
|
|
let brandShortName = brandBundle.getString("brandShortName");
|
|
|
|
|
|
let introTitle = gNavigatorBundle.getFormattedString("contentBlocking.intro.title",
|
|
[brandShortName]);
|
|
let introDescription;
|
|
// This will be sent to the onboarding website to let them know which
|
|
// UI variation we're showing.
|
|
let variation;
|
|
// We show a different UI tour variation for users that already have TP
|
|
// enabled globally.
|
|
if (TrackingProtection.enabledGlobally) {
|
|
introDescription = gNavigatorBundle.getString("contentBlocking.intro.v2.description");
|
|
variation = 2;
|
|
} else {
|
|
introDescription = gNavigatorBundle.getFormattedString("contentBlocking.intro.v1.description",
|
|
[brandShortName]);
|
|
variation = 1;
|
|
}
|
|
|
|
let openStep2 = () => {
|
|
// When the user proceeds in the tour, adjust the counter to indicate that
|
|
// the user doesn't need to see the intro anymore.
|
|
this.dontShowIntroPanelAgain();
|
|
|
|
let nextURL = Services.urlFormatter.formatURLPref("privacy.trackingprotection.introURL") +
|
|
`?step=2&newtab=true&variation=${variation}`;
|
|
switchToTabHavingURI(nextURL, true, {
|
|
// Ignore the fragment in case the intro is shown on the tour page
|
|
// (e.g. if the user manually visited the tour or clicked the link from
|
|
// about:privatebrowsing) so we can avoid a reload.
|
|
ignoreFragment: "whenComparingAndReplace",
|
|
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
|
});
|
|
};
|
|
|
|
let buttons = [
|
|
{
|
|
label: gNavigatorBundle.getString("trackingProtection.intro.step1of3"),
|
|
style: "text",
|
|
},
|
|
{
|
|
callback: openStep2,
|
|
label: gNavigatorBundle.getString("trackingProtection.intro.nextButton.label"),
|
|
style: "primary",
|
|
},
|
|
];
|
|
|
|
let panelTarget = await UITour.getTarget(window, "trackingProtection");
|
|
UITour.initForBrowser(gBrowser.selectedBrowser, window);
|
|
UITour.showInfo(window, panelTarget, introTitle, introDescription, undefined, buttons,
|
|
{ closeButtonCallback: () => this.dontShowIntroPanelAgain() });
|
|
},
|
|
};
|