зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1501992 - Add a sub-panel for Cookies in the control center. r=Ehsan
Differential Revision: https://phabricator.services.mozilla.com/D12596 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
8dc2c13bb7
Коммит
ebcc4dd058
|
@ -7,7 +7,6 @@ var 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",
|
||||
PREF_TRACKING_TABLE: "urlclassifier.trackingTable",
|
||||
PREF_TRACKING_ANNOTATION_TABLE: "urlclassifier.trackingAnnotationTable",
|
||||
enabledGlobally: false,
|
||||
|
@ -19,6 +18,12 @@ var TrackingProtection = {
|
|||
document.getElementById("identity-popup-content-blocking-category-tracking-protection");
|
||||
},
|
||||
|
||||
get categoryLabel() {
|
||||
delete this.categoryLabel;
|
||||
return this.categoryLabel =
|
||||
document.getElementById("identity-popup-content-blocking-tracking-protection-state-label");
|
||||
},
|
||||
|
||||
get subViewList() {
|
||||
delete this.subViewList;
|
||||
return this.subViewList = document.getElementById("identity-popup-trackersView-list");
|
||||
|
@ -29,13 +34,20 @@ var TrackingProtection = {
|
|||
return this.strictInfo = document.getElementById("identity-popup-trackersView-strict-info");
|
||||
},
|
||||
|
||||
strings: {
|
||||
get subViewBlocked() {
|
||||
delete this.subViewBlocked;
|
||||
return this.subViewBlocked =
|
||||
gNavigatorBundle.getString("contentBlocking.trackersView.blocked.label");
|
||||
},
|
||||
},
|
||||
|
||||
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);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "trackingTable", this.PREF_TRACKING_TABLE, false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "trackingAnnotationTable", this.PREF_TRACKING_ANNOTATION_TABLE, false);
|
||||
},
|
||||
|
@ -60,14 +72,29 @@ var TrackingProtection = {
|
|||
Services.prefs.getBoolPref(this.PREF_ENABLED_GLOBALLY);
|
||||
this.enabledInPrivateWindows =
|
||||
Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
|
||||
this.updateCategoryLabel();
|
||||
},
|
||||
|
||||
isBlockerActivated(state) {
|
||||
return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
|
||||
updateCategoryLabel() {
|
||||
let label;
|
||||
if (this.enabled) {
|
||||
label = "contentBlocking.trackers.blocked.label";
|
||||
} else {
|
||||
label = "contentBlocking.trackers.allowed.label";
|
||||
}
|
||||
this.categoryLabel.textContent = gNavigatorBundle.getString(label);
|
||||
},
|
||||
|
||||
isBlocking(state) {
|
||||
return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0;
|
||||
},
|
||||
|
||||
isAllowing(state) {
|
||||
return state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
|
||||
return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0;
|
||||
},
|
||||
|
||||
isDetected(state) {
|
||||
return this.isBlocking(state) || this.isAllowing(state);
|
||||
},
|
||||
|
||||
async updateSubView() {
|
||||
|
@ -114,7 +141,7 @@ var TrackingProtection = {
|
|||
let isAllowed = false;
|
||||
for (let [state] of actions) {
|
||||
isAllowed = isAllowed || this.isAllowing(state);
|
||||
isDetected = isDetected || isAllowed || this.isBlockerActivated(state);
|
||||
isDetected = isDetected || isAllowed || this.isBlocking(state);
|
||||
}
|
||||
|
||||
if (!isDetected) {
|
||||
|
@ -132,17 +159,30 @@ var TrackingProtection = {
|
|||
}
|
||||
|
||||
let listItem = document.createXULElement("hbox");
|
||||
listItem.className = "identity-popup-trackersView-list-item";
|
||||
listItem.className = "identity-popup-content-blocking-list-item";
|
||||
listItem.classList.toggle("allowed", isAllowed);
|
||||
// Repeat the host in the tooltip in case it's too long
|
||||
// and overflows in our panel.
|
||||
listItem.tooltipText = uri.host;
|
||||
|
||||
let image = document.createXULElement("image");
|
||||
image.className = "identity-popup-trackersView-icon";
|
||||
image.classList.toggle("allowed", isAllowed);
|
||||
listItem.append(image);
|
||||
|
||||
let label = document.createXULElement("label");
|
||||
label.value = uri.host;
|
||||
label.className = "identity-popup-content-blocking-list-host-label";
|
||||
label.setAttribute("crop", "end");
|
||||
listItem.append(label);
|
||||
|
||||
if (!isAllowed) {
|
||||
let stateLabel = document.createXULElement("label");
|
||||
stateLabel.value = this.strings.subViewBlocked;
|
||||
stateLabel.className = "identity-popup-content-blocking-list-state-label";
|
||||
listItem.append(stateLabel);
|
||||
}
|
||||
|
||||
return listItem;
|
||||
},
|
||||
};
|
||||
|
@ -157,12 +197,36 @@ var ThirdPartyCookies = {
|
|||
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");
|
||||
document.getElementById("identity-popup-content-blocking-category-cookies");
|
||||
},
|
||||
|
||||
get categoryLabel() {
|
||||
delete this.categoryLabel;
|
||||
return this.categoryLabel =
|
||||
document.getElementById("identity-popup-content-blocking-cookies-state-label");
|
||||
},
|
||||
|
||||
get subViewList() {
|
||||
delete this.subViewList;
|
||||
return this.subViewList = document.getElementById("identity-popup-cookiesView-list");
|
||||
},
|
||||
|
||||
strings: {
|
||||
get subViewAllowed() {
|
||||
delete this.subViewAllowed;
|
||||
return this.subViewAllowed =
|
||||
gNavigatorBundle.getString("contentBlocking.cookiesView.allowed.label");
|
||||
},
|
||||
|
||||
get subViewBlocked() {
|
||||
delete this.subViewBlocked;
|
||||
return this.subViewBlocked =
|
||||
gNavigatorBundle.getString("contentBlocking.cookiesView.blocked.label");
|
||||
},
|
||||
},
|
||||
|
||||
get reportBreakageLabel() {
|
||||
|
@ -183,40 +247,236 @@ var ThirdPartyCookies = {
|
|||
}
|
||||
},
|
||||
|
||||
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;
|
||||
let label;
|
||||
switch (this.behaviorPref) {
|
||||
case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
|
||||
label = "contentBlocking.cookies.3rdPartyBlocked.label";
|
||||
break;
|
||||
case Ci.nsICookieService.BEHAVIOR_REJECT:
|
||||
label = "contentBlocking.cookies.allBlocked.label";
|
||||
break;
|
||||
case Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN:
|
||||
label = "contentBlocking.cookies.unvisitedBlocked.label";
|
||||
break;
|
||||
case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
|
||||
label = "contentBlocking.cookies.trackersBlocked.label";
|
||||
break;
|
||||
default:
|
||||
Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
|
||||
// fall through
|
||||
case Ci.nsICookieService.BEHAVIOR_ACCEPT:
|
||||
label = "contentBlocking.cookies.allowed.label";
|
||||
break;
|
||||
}
|
||||
this.categoryLabel.textContent = gNavigatorBundle.getString(label);
|
||||
},
|
||||
|
||||
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) {
|
||||
isBlocking(state) {
|
||||
return (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER) != 0 ||
|
||||
(state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_ALL) != 0 ||
|
||||
(state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_BY_PERMISSION) != 0 ||
|
||||
(state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN) != 0;
|
||||
},
|
||||
|
||||
isDetected(state) {
|
||||
return (state & Ci.nsIWebProgressListener.STATE_COOKIES_LOADED) != 0;
|
||||
},
|
||||
|
||||
async updateSubView() {
|
||||
let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog();
|
||||
let contentBlockingLog = JSON.parse(contentBlockingLogJSON);
|
||||
|
||||
let categories = this._processContentBlockingLog(contentBlockingLog);
|
||||
|
||||
this.subViewList.textContent = "";
|
||||
|
||||
for (let category of ["firstParty", "trackers", "thirdParty"]) {
|
||||
if (categories[category].length) {
|
||||
let box = document.createXULElement("vbox");
|
||||
let label = document.createXULElement("label");
|
||||
label.className = "identity-popup-cookiesView-list-header";
|
||||
label.textContent = gNavigatorBundle.getString(`contentBlocking.cookiesView.${category}.label`);
|
||||
box.appendChild(label);
|
||||
for (let info of categories[category]) {
|
||||
box.appendChild(this._createListItem(info));
|
||||
}
|
||||
this.subViewList.appendChild(box);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_hasException(origin) {
|
||||
for (let perm of Services.perms.getAllForPrincipal(gBrowser.contentPrincipal)) {
|
||||
if (perm.type == "3rdPartyStorage^" + origin || perm.type.startsWith("3rdPartyStorage^" + origin + "^")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
|
||||
// Cookie exceptions get "inherited" from parent- to sub-domain, so we need to
|
||||
// make sure to include parent domains in the permission check for "cookies".
|
||||
return Services.perms.testPermissionFromPrincipal(principal, "cookie") != Services.perms.UNKNOWN_ACTION;
|
||||
},
|
||||
|
||||
_clearException(origin) {
|
||||
for (let perm of Services.perms.getAllForPrincipal(gBrowser.contentPrincipal)) {
|
||||
if (perm.type == "3rdPartyStorage^" + origin || perm.type.startsWith("3rdPartyStorage^" + origin + "^")) {
|
||||
Services.perms.removePermission(perm);
|
||||
}
|
||||
}
|
||||
|
||||
// OAs don't matter here, so we can just use the hostname.
|
||||
let host = Services.io.newURI(origin).host;
|
||||
|
||||
// Cookie exceptions get "inherited" from parent- to sub-domain, so we need to
|
||||
// clear any cookie permissions from parent domains as well.
|
||||
for (let perm of Services.perms.enumerator) {
|
||||
if (perm.type == "cookie" &&
|
||||
Services.eTLD.hasRootDomain(host, perm.principal.URI.host)) {
|
||||
Services.perms.removePermission(perm);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Transforms and filters cookie entries in the content blocking log
|
||||
// so that we can categorize and display them in the UI.
|
||||
_processContentBlockingLog(log) {
|
||||
let newLog = {
|
||||
firstParty: [],
|
||||
trackers: [],
|
||||
thirdParty: [],
|
||||
};
|
||||
|
||||
let firstPartyDomain = null;
|
||||
try {
|
||||
firstPartyDomain = Services.eTLD.getBaseDomain(gBrowser.currentURI);
|
||||
} catch (e) {
|
||||
// There are nasty edge cases here where someone is trying to set a cookie
|
||||
// on a public suffix or an IP address. Just categorize those as third party...
|
||||
if (e.result != Cr.NS_ERROR_HOST_IS_IP_ADDRESS &&
|
||||
e.result != Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
for (let [origin, actions] of Object.entries(log)) {
|
||||
if (!origin.startsWith("http")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let info = {origin, isAllowed: true, hasException: this._hasException(origin)};
|
||||
let hasCookie = false;
|
||||
let isTracker = false;
|
||||
|
||||
// Extract information from the states entries in the content blocking log.
|
||||
// Each state will contain a single state flag from nsIWebProgressListener.
|
||||
// Note that we are using the same helper functions that are applied to the
|
||||
// bit map passed to onSecurityChange (which contains multiple states), thus
|
||||
// not checking exact equality, just presence of bits.
|
||||
for (let [state, blocked] of actions) {
|
||||
if (this.isDetected(state)) {
|
||||
hasCookie = true;
|
||||
}
|
||||
if (TrackingProtection.isAllowing(state)) {
|
||||
isTracker = true;
|
||||
}
|
||||
// blocked tells us whether the resource was actually blocked
|
||||
// (which it may not be in case of an exception).
|
||||
if (this.isBlocking(state) && blocked) {
|
||||
info.isAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCookie) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let isFirstParty = false;
|
||||
try {
|
||||
let uri = Services.io.newURI(origin);
|
||||
isFirstParty = Services.eTLD.getBaseDomain(uri) == firstPartyDomain;
|
||||
} catch (e) {
|
||||
if (e.result != Cr.NS_ERROR_HOST_IS_IP_ADDRESS &&
|
||||
e.result != Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFirstParty) {
|
||||
newLog.firstParty.push(info);
|
||||
} else if (isTracker) {
|
||||
newLog.trackers.push(info);
|
||||
} else {
|
||||
newLog.thirdParty.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
return newLog;
|
||||
},
|
||||
|
||||
_createListItem({origin, isAllowed, hasException}) {
|
||||
let listItem = document.createXULElement("hbox");
|
||||
listItem.className = "identity-popup-content-blocking-list-item";
|
||||
listItem.classList.toggle("allowed", isAllowed);
|
||||
// Repeat the origin in the tooltip in case it's too long
|
||||
// and overflows in our panel.
|
||||
listItem.tooltipText = origin;
|
||||
|
||||
let image = document.createXULElement("image");
|
||||
image.className = "identity-popup-cookiesView-icon";
|
||||
image.classList.toggle("allowed", isAllowed);
|
||||
listItem.append(image);
|
||||
|
||||
let label = document.createXULElement("label");
|
||||
label.value = origin;
|
||||
label.className = "identity-popup-content-blocking-list-host-label";
|
||||
label.setAttribute("crop", "end");
|
||||
listItem.append(label);
|
||||
|
||||
let stateLabel;
|
||||
if (isAllowed && hasException) {
|
||||
stateLabel = document.createXULElement("label");
|
||||
stateLabel.value = this.strings.subViewAllowed;
|
||||
stateLabel.className = "identity-popup-content-blocking-list-state-label";
|
||||
listItem.append(stateLabel);
|
||||
} else if (!isAllowed) {
|
||||
stateLabel = document.createXULElement("label");
|
||||
stateLabel.value = this.strings.subViewBlocked;
|
||||
stateLabel.className = "identity-popup-content-blocking-list-state-label";
|
||||
listItem.append(stateLabel);
|
||||
}
|
||||
|
||||
if (hasException) {
|
||||
let removeException = document.createXULElement("button");
|
||||
removeException.className = "identity-popup-permission-remove-button";
|
||||
removeException.tooltipText = gNavigatorBundle.getFormattedString(
|
||||
"contentBlocking.cookiesView.removeButton.tooltip", [origin]);
|
||||
removeException.addEventListener("click", () => {
|
||||
this._clearException(origin);
|
||||
// Just flip the display based on what state we had previously.
|
||||
stateLabel.value = isAllowed ? this.strings.subViewBlocked : this.strings.subViewAllowed;
|
||||
listItem.classList.toggle("allowed", !isAllowed);
|
||||
image.classList.toggle("allowed", !isAllowed);
|
||||
removeException.hidden = true;
|
||||
});
|
||||
listItem.append(removeException);
|
||||
}
|
||||
|
||||
return listItem;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -397,11 +657,9 @@ var ContentBlocking = {
|
|||
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`;
|
||||
|
@ -447,6 +705,11 @@ var ContentBlocking = {
|
|||
this.identityPopupMultiView.showSubView("identity-popup-trackersView");
|
||||
},
|
||||
|
||||
async showCookiesSubview() {
|
||||
await ThirdPartyCookies.updateSubView();
|
||||
this.identityPopupMultiView.showSubView("identity-popup-cookiesView");
|
||||
},
|
||||
|
||||
shieldHistogramAdd(value) {
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
return;
|
||||
|
@ -473,27 +736,22 @@ var ContentBlocking = {
|
|||
this.iconBox.removeAttribute("animate");
|
||||
}
|
||||
|
||||
let anyBlockerActivated = false;
|
||||
let anyDetected = false;
|
||||
let anyBlocking = 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.activated = blocker.isBlocking(state);
|
||||
blocker.categoryItem.classList.toggle("blocked", blocker.enabled);
|
||||
blocker.categoryItem.hidden = !blocker.visible;
|
||||
anyBlockerActivated = anyBlockerActivated || blocker.activated;
|
||||
let detected = blocker.isDetected(state);
|
||||
blocker.categoryItem.hidden = !detected;
|
||||
anyDetected = anyDetected || detected;
|
||||
anyBlocking = anyBlocking || 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 = 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.
|
||||
|
@ -501,11 +759,15 @@ var ContentBlocking = {
|
|||
let hasException = Services.perms.testExactPermission(baseURI, type) ==
|
||||
Services.perms.ALLOW_ACTION;
|
||||
|
||||
this.content.toggleAttribute("detected", detected);
|
||||
// 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.
|
||||
this.content.toggleAttribute("detected", anyDetected);
|
||||
this.content.toggleAttribute("blocking", anyBlocking);
|
||||
this.content.toggleAttribute("hasException", hasException);
|
||||
this.content.toggleAttribute("active", active);
|
||||
|
||||
this.iconBox.toggleAttribute("active", active);
|
||||
this.iconBox.toggleAttribute("active", anyBlocking);
|
||||
this.iconBox.toggleAttribute("hasException", hasException);
|
||||
|
||||
// For release (due to the large volume) we only want to receive reports
|
||||
|
@ -521,7 +783,7 @@ var ContentBlocking = {
|
|||
|
||||
if (isSimulated) {
|
||||
this.iconBox.removeAttribute("animate");
|
||||
} else if (active && webProgress.isTopLevel) {
|
||||
} else if (anyBlocking && webProgress.isTopLevel) {
|
||||
this.iconBox.setAttribute("animate", "true");
|
||||
|
||||
if (!isBrowserPrivate) {
|
||||
|
@ -537,7 +799,7 @@ var ContentBlocking = {
|
|||
if (hasException) {
|
||||
this.iconBox.setAttribute("tooltiptext", this.disabledTooltipText);
|
||||
this.shieldHistogramAdd(1);
|
||||
} else if (active) {
|
||||
} else if (anyBlocking) {
|
||||
this.iconBox.setAttribute("tooltiptext", this.activeTooltipText);
|
||||
this.shieldHistogramAdd(2);
|
||||
} else {
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
const TP_PREF = "privacy.trackingprotection.enabled";
|
||||
const TPC_PREF = "network.cookie.cookieBehavior";
|
||||
const TP_UI_PREF = "browser.contentblocking.trackingprotection.control-center.ui.enabled";
|
||||
const RT_UI_PREF = "browser.contentblocking.rejecttrackers.control-center.ui.enabled";
|
||||
const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
|
||||
|
||||
async function waitAndAssertPreferencesShown() {
|
||||
|
|
|
@ -186,11 +186,9 @@ add_task(async function testReportBreakage() {
|
|||
let prefs = [
|
||||
"privacy.trackingprotection.enabled",
|
||||
"privacy.trackingprotection.pbmode.enabled",
|
||||
"browser.contentblocking.trackingprotection.control-center.ui.enabled",
|
||||
"urlclassifier.trackingTable",
|
||||
"network.http.referer.defaultPolicy",
|
||||
"network.http.referer.defaultPolicy.pbmode",
|
||||
"browser.contentblocking.rejecttrackers.control-center.ui.enabled",
|
||||
"network.cookie.cookieBehavior",
|
||||
"network.cookie.lifetimePolicy",
|
||||
"privacy.restrict3rdpartystorage.expiration",
|
||||
|
|
|
@ -74,27 +74,20 @@
|
|||
|
||||
<vbox id="identity-popup-content-blocking-category-list">
|
||||
<toolbarbutton id="identity-popup-content-blocking-category-tracking-protection"
|
||||
onclick="ContentBlocking.showTrackersSubview()"
|
||||
class="identity-popup-content-blocking-category" align="center">
|
||||
onclick="ContentBlocking.showTrackersSubview()"
|
||||
class="identity-popup-content-blocking-category" align="center">
|
||||
<image class="identity-popup-content-blocking-category-icon tracking-protection-icon"/>
|
||||
<label flex="1" class="identity-popup-content-blocking-category-label">&contentBlocking.trackingProtection3.label;</label>
|
||||
<label flex="1" id="identity-popup-content-blocking-tracking-protection-label-allowed"
|
||||
class="identity-popup-content-blocking-category-state-label">&contentBlocking.trackingProtection.allowed.label;</label>
|
||||
<label flex="1" id="identity-popup-content-blocking-tracking-protection-label-blocked"
|
||||
class="identity-popup-content-blocking-category-state-label">&contentBlocking.trackingProtection.blocked.label;</label>
|
||||
<label flex="1" id="identity-popup-content-blocking-tracking-protection-state-label" class="identity-popup-content-blocking-category-state-label"/>
|
||||
</toolbarbutton>
|
||||
<hbox id="identity-popup-content-blocking-category-3rdpartycookies"
|
||||
class="identity-popup-content-blocking-category" align="center" role="group">
|
||||
<toolbarbutton id="identity-popup-content-blocking-category-cookies"
|
||||
onclick="ContentBlocking.showCookiesSubview()"
|
||||
class="identity-popup-content-blocking-category" align="center">
|
||||
<image class="identity-popup-content-blocking-category-icon thirdpartycookies-icon"/>
|
||||
<label flex="1" id="identity-popup-content-blocking-category-label-default"
|
||||
class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.label;</label>
|
||||
<label flex="1" id="identity-popup-content-blocking-category-label-trackers"
|
||||
hidden="true" class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.trackers.label;</label>
|
||||
<label flex="1" class="identity-popup-content-blocking-category-state-label">&contentBlocking.3rdPartyCookies.blocking.label;</label>
|
||||
<label flex="1" class="identity-popup-content-blocking-category-add-blocking text-link"
|
||||
id="identity-popup-3rdpartycookies-add-blocking"
|
||||
onclick="ContentBlocking.openPreferences('identityPopup-CB-3rdpartycookies'); gIdentityHandler.recordClick('cookies_add_blocking');">&contentBlocking.3rdPartyCookies.add.label;</label>
|
||||
</hbox>
|
||||
class="identity-popup-content-blocking-category-label">&contentBlocking.cookies.label;</label>
|
||||
<label flex="1" id="identity-popup-content-blocking-cookies-state-label" class="identity-popup-content-blocking-category-state-label"/>
|
||||
</toolbarbutton>
|
||||
</vbox>
|
||||
|
||||
<button id="tracking-action-unblock"
|
||||
|
@ -246,7 +239,7 @@
|
|||
role="document"
|
||||
title="&contentBlocking.trackersView.label;"
|
||||
descriptionheightworkaround="true">
|
||||
<vbox id="identity-popup-trackersView-list">
|
||||
<vbox id="identity-popup-trackersView-list" class="identity-popup-content-blocking-list">
|
||||
</vbox>
|
||||
<hbox id="identity-popup-trackersView-strict-info">
|
||||
<image/>
|
||||
|
@ -260,6 +253,21 @@
|
|||
</vbox>
|
||||
</panelview>
|
||||
|
||||
<!-- Cookies SubView -->
|
||||
<panelview id="identity-popup-cookiesView"
|
||||
role="document"
|
||||
title="&contentBlocking.cookiesView.label;"
|
||||
descriptionheightworkaround="true">
|
||||
<vbox id="identity-popup-cookiesView-list" class="identity-popup-content-blocking-list">
|
||||
</vbox>
|
||||
<vbox class="identity-popup-footer">
|
||||
<button id="identity-popup-cookiesView-settings-button"
|
||||
label="&contentBlocking.manageSettings.label;"
|
||||
accesskey="&contentBlocking.manageSettings.accesskey;"
|
||||
oncommand="ContentBlocking.openPreferences();"/>
|
||||
</vbox>
|
||||
</panelview>
|
||||
|
||||
<!-- Report Breakage SubView -->
|
||||
<panelview id="identity-popup-breakageReportView"
|
||||
title="&contentBlocking.breakageReportView.label;"
|
||||
|
|
|
@ -969,37 +969,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
|||
<!ENTITY contentBlocking.notDetected "No blockable content detected on this page.">
|
||||
|
||||
<!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">
|
||||
<!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.blocked.label):
|
||||
This label signals that this type of content blocking is turned
|
||||
ON and is successfully blocking tracker content, so this is
|
||||
a positive thing. It forms the end of the (imaginary) sentence
|
||||
"Trackers [are] Blocked"-->
|
||||
<!ENTITY contentBlocking.trackingProtection.blocked.label "Blocked">
|
||||
|
||||
<!ENTITY contentBlocking.3rdPartyCookies.label "Third-Party Cookies">
|
||||
<!ENTITY contentBlocking.3rdPartyCookies.trackers.label "Tracking Cookies">
|
||||
<!-- LOCALIZATION NOTE (contentBlocking.3rdPartyCookies.blocked.label):
|
||||
This label signals that this type of content blocking is turned
|
||||
ON and is successfully blocking third-party cookies, so this is
|
||||
a positive thing. It forms the end of the (imaginary) sentence
|
||||
"Third-Party Cookies [are] Blocked"-->
|
||||
<!ENTITY contentBlocking.3rdPartyCookies.blocked.label "Blocked">
|
||||
<!-- LOCALIZATION NOTE (contentBlocking.tranckingProtection.blocking.label):
|
||||
This label signals that this type of content blocking is turned
|
||||
ON, so this is a positive thing. It forms the verb in the (imaginary) sentence
|
||||
"Firefox is blocking Third-Party Cookies"-->
|
||||
<!ENTITY contentBlocking.3rdPartyCookies.blocking.label "Blocking">
|
||||
<!-- LOCALIZATION NOTE (contentBlocking.3rdPartyCookies.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.3rdPartyCookies.add.label "Add Blocking…">
|
||||
|
||||
<!ENTITY contentBlocking.manageSettings.label "Manage Content Blocking">
|
||||
<!ENTITY contentBlocking.manageSettings.accesskey "M">
|
||||
|
@ -1007,6 +976,9 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
|||
<!ENTITY contentBlocking.trackersView.label "Trackers">
|
||||
<!ENTITY contentBlocking.trackersView.strictInfo.label "To block all trackers, set content blocking to “Strict”.">
|
||||
|
||||
<!ENTITY contentBlocking.cookies.label "Cookies">
|
||||
<!ENTITY contentBlocking.cookiesView.label "Cookies and Site Data">
|
||||
|
||||
<!ENTITY contentBlocking.openBreakageReportView2.label "Report a problem">
|
||||
<!ENTITY contentBlocking.breakageReportView.label "Report Problems">
|
||||
<!ENTITY contentBlocking.breakageReportView2.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 browser settings to Mozilla.)">
|
||||
|
|
|
@ -505,6 +505,49 @@ contentBlocking.category.standard=Standard
|
|||
contentBlocking.category.strict=Strict
|
||||
contentBlocking.category.custom=Custom
|
||||
|
||||
# LOCALIZATION NOTE (contentBlocking.trackers.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"
|
||||
contentBlocking.trackers.allowed.label=Allowed
|
||||
# LOCALIZATION NOTE (contentBlocking.trackers.blocked.label):
|
||||
# This label signals that this type of content blocking is turned
|
||||
# ON and is successfully blocking tracker content, so this is
|
||||
# a positive thing. It forms the end of the (imaginary) sentence
|
||||
# "Trackers [are] Blocked"
|
||||
contentBlocking.trackers.blocked.label=Blocked
|
||||
|
||||
# LOCALIZATION NOTE (contentBlocking.trackersView.blocked.label):
|
||||
# This label is shown next to a tracker in the trackers subview.
|
||||
# It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
|
||||
contentBlocking.trackersView.blocked.label=Blocked
|
||||
|
||||
# LOCALIZATION NOTE (contentBlocking.cookies.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
|
||||
# "Cookies [are] Allowed"
|
||||
contentBlocking.cookies.allowed.label=Allowed
|
||||
contentBlocking.cookies.trackersBlocked.label=Tracking Cookies Blocked
|
||||
contentBlocking.cookies.3rdPartyBlocked.label=Third-Party Cookies Blocked
|
||||
contentBlocking.cookies.unvisitedBlocked.label=Unvisited Site Cookies Blocked
|
||||
contentBlocking.cookies.allBlocked.label=All Cookies Blocked
|
||||
|
||||
contentBlocking.cookiesView.firstParty.label=From This Site
|
||||
contentBlocking.cookiesView.trackers.label=Tracking Cookies
|
||||
contentBlocking.cookiesView.thirdParty.label=Third-Party Cookies
|
||||
# LOCALIZATION NOTE (contentBlocking.cookiesView.allowed.label):
|
||||
# This label is shown next to a cookie origin in the cookies subview.
|
||||
# It forms the end of the (imaginary) sentence "www.example.com [was] Allowed"
|
||||
contentBlocking.cookiesView.allowed.label=Allowed
|
||||
# LOCALIZATION NOTE (contentBlocking.cookiesView.blocked.label):
|
||||
# This label is shown next to a cookie origin in the cookies subview.
|
||||
# It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
|
||||
contentBlocking.cookiesView.blocked.label=Blocked
|
||||
# LOCALIZATION NOTE (contentBlocking.cookiesView.removeButton.tooltip): %S is the domain of the site.
|
||||
contentBlocking.cookiesView.removeButton.tooltip=Clear cookie exception for %S
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -165,7 +165,8 @@
|
|||
.identity-popup-footer,
|
||||
.tracking-protection-button,
|
||||
#identity-popup-trackersView-strict-info > label,
|
||||
.identity-popup-trackersView-list-item > label,
|
||||
.identity-popup-cookiesView-list-header,
|
||||
.identity-popup-content-blocking-list-item > label,
|
||||
#identity-popup-mainView-panel-header > label,
|
||||
#identity-popup-trackersView > .panel-header,
|
||||
#identity-popup-securityView > .panel-header,
|
||||
|
@ -403,66 +404,95 @@ description#identity-popup-content-verifier,
|
|||
background-image: url("chrome://browser/skin/controlcenter/tracking-protection.svg");
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection {
|
||||
.identity-popup-content-blocking-category {
|
||||
/* Overwrite toolbarbutton styles */
|
||||
-moz-appearance: none;
|
||||
margin: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection:-moz-focusring,
|
||||
#identity-popup-content-blocking-category-tracking-protection:hover {
|
||||
.identity-popup-content-blocking-category:-moz-focusring,
|
||||
.identity-popup-content-blocking-category:hover {
|
||||
border-radius: 2px;
|
||||
background-color: var(--arrowpanel-dimmed-further);
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection:hover:active {
|
||||
.identity-popup-content-blocking-category:hover:active {
|
||||
background-color: var(--arrowpanel-dimmed-even-further);
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection::after {
|
||||
.identity-popup-content-blocking-category::after {
|
||||
content: url(chrome://browser/skin/back-12.svg);
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
transform: scaleX(-1) translateY(1px);
|
||||
float: right;
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection:-moz-locale-dir(rtl)::after {
|
||||
.identity-popup-content-blocking-category:-moz-locale-dir(rtl)::after {
|
||||
transform: scaleX(1) translateY(1px);
|
||||
}
|
||||
|
||||
/* This subview could get filled with a lot of trackers, set a maximum size
|
||||
* and allow it to scroll vertically.*/
|
||||
#identity-popup-cookiesView,
|
||||
#identity-popup-trackersView {
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
#identity-popup-trackersView-list {
|
||||
.identity-popup-cookiesView-list-header {
|
||||
color: var(--panel-disabled-color);
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.identity-popup-content-blocking-list {
|
||||
padding: 5px 20px;
|
||||
-moz-box-flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-list-item {
|
||||
.identity-popup-content-blocking-list-item {
|
||||
margin: 5px 0;
|
||||
overflow: hidden;
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-list-item > label {
|
||||
/* Limit to full width - container padding - icon width - icon margin */
|
||||
max-width: calc(var(--identity-popup-width) - 40px - 16px - 10px);
|
||||
.identity-popup-content-blocking-list-item:not(.allowed) {
|
||||
color: var(--panel-disabled-color);
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-list-item > image {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
|
||||
.identity-popup-content-blocking-list-host-label {
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
.identity-popup-content-blocking-list-state-label {
|
||||
-moz-box-flex: 1;
|
||||
text-align: end;
|
||||
margin-inline-start: 5px;
|
||||
margin-inline-end: 2px;
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-icon,
|
||||
.identity-popup-cookiesView-icon {
|
||||
margin-inline-end: 10px;
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-list-item.allowed > image {
|
||||
.identity-popup-trackersView-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
|
||||
}
|
||||
|
||||
.identity-popup-trackersView-icon.allowed {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/trackers.svg);
|
||||
}
|
||||
|
||||
.identity-popup-cookiesView-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies-disabled.svg);
|
||||
}
|
||||
|
||||
.identity-popup-cookiesView-icon.allowed {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies.svg);
|
||||
}
|
||||
|
||||
#identity-popup-trackersView-strict-info {
|
||||
min-height: 40px;
|
||||
/* Limit to full width - margin */
|
||||
|
@ -497,51 +527,20 @@ description#identity-popup-content-verifier,
|
|||
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 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show the "detected"/"not detected" message depending on the content state. */
|
||||
#identity-popup-content-blocking-content:not([detected]) > #identity-popup-content-blocking-detected,
|
||||
#identity-popup-content-blocking-content[detected] > #identity-popup-content-blocking-not-detected {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.identity-popup-content-blocking-category-state-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* TODO: This will be cleaned up by bug 1501992 */
|
||||
/* Hide the state label unless we blocked something only for third party cookies */
|
||||
#identity-popup-content-blocking-content:not([hasException]) #identity-popup-content-blocking-category-3rdpartycookies.blocked .identity-popup-content-blocking-category-state-label,
|
||||
/* For trackers, either show a "blocked" or "allowed" label depending on the state. */
|
||||
#identity-popup-content-blocking-content:not([hasException]) #identity-popup-content-blocking-category-tracking-protection.blocked > #identity-popup-content-blocking-tracking-protection-label-blocked,
|
||||
#identity-popup-content-blocking-category-tracking-protection:not(.blocked) > #identity-popup-content-blocking-tracking-protection-label-allowed,
|
||||
#identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-tracking-protection-label-allowed {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
.identity-popup-content-blocking-category.blocked .identity-popup-content-blocking-category-add-blocking {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tracking-protection-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/trackers.svg);
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-tracking-protection.blocked > .tracking-protection-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
|
||||
}
|
||||
|
||||
.thirdpartycookies-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies.svg);
|
||||
}
|
||||
|
||||
#identity-popup-content-blocking-category-3rdpartycookies.blocked > .thirdpartycookies-icon {
|
||||
list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies-disabled.svg);
|
||||
}
|
||||
|
||||
/* Content Blocking action button */
|
||||
|
||||
.tracking-protection-button {
|
||||
|
@ -598,15 +597,15 @@ description#identity-popup-content-verifier,
|
|||
/* Hide the "report breakage" button if 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([active]):not([hasException]) #identity-popup-content-blocking-report-breakage {
|
||||
#identity-popup-content-blocking-content:not([blocking]):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[active]:not([hasException]) > #tracking-action-unblock,
|
||||
#main-window:not([privatebrowsingmode]) #identity-popup-content-blocking-content[blocking]:not([hasException]) > #tracking-action-unblock,
|
||||
/* Offer to permanently add an exception in normal mode. */
|
||||
#main-window[privatebrowsingmode] #identity-popup-content-blocking-content[active]:not([hasException]) > #tracking-action-unblock-private,
|
||||
#main-window[privatebrowsingmode] #identity-popup-content-blocking-content[blocking]:not([hasException]) > #tracking-action-unblock-private,
|
||||
/* If there's an exception just offer to remove the exception again. */
|
||||
#identity-popup-content-blocking-content[hasException] > #tracking-action-block {
|
||||
display: -moz-box;
|
||||
|
@ -718,6 +717,7 @@ description#identity-popup-content-verifier,
|
|||
background-color: transparent;
|
||||
color: inherit;
|
||||
opacity: 0.6;
|
||||
margin-inline-start: 2px;
|
||||
}
|
||||
|
||||
.identity-popup-permission-remove-button > .button-box {
|
||||
|
|
|
@ -628,8 +628,6 @@ security.ui.identitypopup:
|
|||
- firefox
|
||||
click:
|
||||
objects: [
|
||||
"tp_add_blocking",
|
||||
"cookies_add_blocking",
|
||||
"cb_prefs_button",
|
||||
"clear_sitedata",
|
||||
"unblock",
|
||||
|
|
Загрузка…
Ссылка в новой задаче