mirror of https://github.com/gorhill/uBlock.git
this (indirectly) fixes #15: let uBlock block remote fonts globally or on a site-basis
This commit is contained in:
parent
ff0ad30ba6
commit
113c2e11a5
|
@ -87,6 +87,10 @@
|
||||||
"message":"Toggle cosmetic filtering for this site",
|
"message":"Toggle cosmetic filtering for this site",
|
||||||
"description":"English: Toggle cosmetic filtering for this site"
|
"description":"English: Toggle cosmetic filtering for this site"
|
||||||
},
|
},
|
||||||
|
"popupTipNoRemoteFonts":{
|
||||||
|
"message":"Toggle the blocking of remote fonts for this site",
|
||||||
|
"description":"English: Toggle the blocking of remote fonts for this site"
|
||||||
|
},
|
||||||
"popupAnyRulePrompt":{
|
"popupAnyRulePrompt":{
|
||||||
"message":"all",
|
"message":"all",
|
||||||
"description":""
|
"description":""
|
||||||
|
|
|
@ -39,7 +39,8 @@ var HnSwitches = function() {
|
||||||
var switchBitOffsets = {
|
var switchBitOffsets = {
|
||||||
'no-strict-blocking': 0,
|
'no-strict-blocking': 0,
|
||||||
'no-popups': 2,
|
'no-popups': 2,
|
||||||
'no-cosmetic-filtering': 4
|
'no-cosmetic-filtering': 4,
|
||||||
|
'no-remote-fonts': 6
|
||||||
};
|
};
|
||||||
|
|
||||||
var fromLegacySwitchNames = {
|
var fromLegacySwitchNames = {
|
||||||
|
@ -104,7 +105,9 @@ HnSwitches.toBroaderHostname = toBroaderHostname;
|
||||||
|
|
||||||
HnSwitches.prototype.reset = function() {
|
HnSwitches.prototype.reset = function() {
|
||||||
this.switches = {};
|
this.switches = {};
|
||||||
|
this.n = '';
|
||||||
this.z = '';
|
this.z = '';
|
||||||
|
this.r = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -221,8 +224,10 @@ HnSwitches.prototype.evaluate = function(switchName, hostname) {
|
||||||
HnSwitches.prototype.evaluateZ = function(switchName, hostname) {
|
HnSwitches.prototype.evaluateZ = function(switchName, hostname) {
|
||||||
var bitOffset = switchBitOffsets[switchName];
|
var bitOffset = switchBitOffsets[switchName];
|
||||||
if ( bitOffset === undefined ) {
|
if ( bitOffset === undefined ) {
|
||||||
|
this.r = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this.n = switchName;
|
||||||
var bits;
|
var bits;
|
||||||
var s = hostname;
|
var s = hostname;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -231,6 +236,7 @@ HnSwitches.prototype.evaluateZ = function(switchName, hostname) {
|
||||||
bits = bits >> bitOffset & 3;
|
bits = bits >> bitOffset & 3;
|
||||||
if ( bits !== 0 ) {
|
if ( bits !== 0 ) {
|
||||||
this.z = s;
|
this.z = s;
|
||||||
|
this.r = bits;
|
||||||
return bits === 1;
|
return bits === 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,11 +245,20 @@ HnSwitches.prototype.evaluateZ = function(switchName, hostname) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.r = 0;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
HnSwitches.prototype.toResultString = function() {
|
||||||
|
return this.r !== 1 ?
|
||||||
|
'' :
|
||||||
|
'ub:' + this.n + ': ' + this.z + ' true';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
HnSwitches.prototype.toString = function() {
|
HnSwitches.prototype.toString = function() {
|
||||||
var out = [];
|
var out = [];
|
||||||
var switchName, val;
|
var switchName, val;
|
||||||
|
|
|
@ -287,6 +287,8 @@ var popupDataFromTabId = function(tabId, tabTitle) {
|
||||||
r.noPopups = µb.hnSwitches.evaluateZ('no-popups', tabContext.rootHostname);
|
r.noPopups = µb.hnSwitches.evaluateZ('no-popups', tabContext.rootHostname);
|
||||||
r.noStrictBlocking = µb.hnSwitches.evaluateZ('no-strict-blocking', tabContext.rootHostname);
|
r.noStrictBlocking = µb.hnSwitches.evaluateZ('no-strict-blocking', tabContext.rootHostname);
|
||||||
r.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', tabContext.rootHostname);
|
r.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', tabContext.rootHostname);
|
||||||
|
r.noRemoteFonts = µb.hnSwitches.evaluateZ('no-remote-fonts', tabContext.rootHostname);
|
||||||
|
r.remoteFontCount = pageStore.remoteFontCount;
|
||||||
} else {
|
} else {
|
||||||
r.hostnameDict = {};
|
r.hostnameDict = {};
|
||||||
r.firewallRules = getFirewallRules();
|
r.firewallRules = getFirewallRules();
|
||||||
|
|
|
@ -305,6 +305,7 @@ PageStore.prototype.init = function(tabId) {
|
||||||
this.perLoadBlockedRequestCount = 0;
|
this.perLoadBlockedRequestCount = 0;
|
||||||
this.perLoadAllowedRequestCount = 0;
|
this.perLoadAllowedRequestCount = 0;
|
||||||
this.hiddenElementCount = ''; // Empty string means "unknown"
|
this.hiddenElementCount = ''; // Empty string means "unknown"
|
||||||
|
this.remoteFontCount = 0;
|
||||||
this.netFilteringCache = NetFilteringResultCache.factory();
|
this.netFilteringCache = NetFilteringResultCache.factory();
|
||||||
|
|
||||||
// Support `elemhide` filter option. Called at this point so the required
|
// Support `elemhide` filter option. Called at this point so the required
|
||||||
|
@ -495,9 +496,10 @@ PageStore.prototype.toggleNetFilteringSwitch = function(url, scope, state) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PageStore.prototype.filterRequest = function(context) {
|
PageStore.prototype.filterRequest = function(context) {
|
||||||
|
var requestType = context.requestType;
|
||||||
|
|
||||||
if ( this.getNetFilteringSwitch() === false ) {
|
if ( this.getNetFilteringSwitch() === false ) {
|
||||||
if ( collapsibleRequestTypes.indexOf(context.requestType) !== -1 ) {
|
if ( collapsibleRequestTypes.indexOf(requestType) !== -1 ) {
|
||||||
this.netFilteringCache.add(context, '');
|
this.netFilteringCache.add(context, '');
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
@ -509,8 +511,19 @@ PageStore.prototype.filterRequest = function(context) {
|
||||||
return entry.result;
|
return entry.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, context.requestType);
|
var result = '';
|
||||||
var result = µb.sessionURLFiltering.toFilterString();
|
|
||||||
|
if ( requestType === 'font' ) {
|
||||||
|
if ( µb.hnSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||||
|
result = µb.hnSwitches.toResultString();
|
||||||
|
}
|
||||||
|
this.remoteFontCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( result === '' ) {
|
||||||
|
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, requestType);
|
||||||
|
result = µb.sessionURLFiltering.toFilterString();
|
||||||
|
}
|
||||||
|
|
||||||
// Given that:
|
// Given that:
|
||||||
// - Dynamic filtering override static filtering
|
// - Dynamic filtering override static filtering
|
||||||
|
@ -518,7 +531,7 @@ PageStore.prototype.filterRequest = function(context) {
|
||||||
// We evaluate dynamic filtering first, and hopefully we can skip
|
// We evaluate dynamic filtering first, and hopefully we can skip
|
||||||
// evaluation of static filtering.
|
// evaluation of static filtering.
|
||||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||||
µb.sessionFirewall.evaluateCellZY( context.rootHostname, context.requestHostname, context.requestType);
|
µb.sessionFirewall.evaluateCellZY( context.rootHostname, context.requestHostname, requestType);
|
||||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||||
result = µb.sessionFirewall.toFilterString();
|
result = µb.sessionFirewall.toFilterString();
|
||||||
}
|
}
|
||||||
|
@ -532,11 +545,11 @@ PageStore.prototype.filterRequest = function(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
|
//console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
|
||||||
if ( collapsibleRequestTypes.indexOf(context.requestType) !== -1 ) {
|
if ( collapsibleRequestTypes.indexOf(requestType) !== -1 ) {
|
||||||
this.netFilteringCache.add(context, result);
|
this.netFilteringCache.add(context, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.debug('[%s, %s] = "%s"', context.requestHostname, context.requestType, result);
|
// console.debug('[%s, %s] = "%s"', context.requestHostname, requestType, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -551,8 +564,20 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, context.requestType);
|
var requestType = context.requestType;
|
||||||
var result = µb.sessionURLFiltering.toFilterString();
|
var result = '';
|
||||||
|
|
||||||
|
if ( requestType === 'font' ) {
|
||||||
|
if ( µb.hnSwitches.evaluateZ('no-remote-fonts', context.rootHostname) !== false ) {
|
||||||
|
result = µb.hnSwitches.toResultString();
|
||||||
|
}
|
||||||
|
this.remoteFontCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( result === '' ) {
|
||||||
|
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, requestType);
|
||||||
|
result = µb.sessionURLFiltering.toFilterString();
|
||||||
|
}
|
||||||
|
|
||||||
// Given that:
|
// Given that:
|
||||||
// - Dynamic filtering override static filtering
|
// - Dynamic filtering override static filtering
|
||||||
|
@ -560,7 +585,7 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
||||||
// We evaluate dynamic filtering first, and hopefully we can skip
|
// We evaluate dynamic filtering first, and hopefully we can skip
|
||||||
// evaluation of static filtering.
|
// evaluation of static filtering.
|
||||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||||
µb.sessionFirewall.evaluateCellZY(context.rootHostname, context.requestHostname, context.requestType);
|
µb.sessionFirewall.evaluateCellZY(context.rootHostname, context.requestHostname, requestType);
|
||||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||||
result = µb.sessionFirewall.toFilterString();
|
result = µb.sessionFirewall.toFilterString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,8 @@ var hashFromPopupData = function(reset) {
|
||||||
}
|
}
|
||||||
hasher.sort();
|
hasher.sort();
|
||||||
hasher.push(uDom('body').hasClass('off'));
|
hasher.push(uDom('body').hasClass('off'));
|
||||||
hasher.push(uDom('#no-cosmetic-filtering').hasClass('on'));
|
hasher.push(uDom.nodeFromId('no-cosmetic-filtering').classList.contains('on'));
|
||||||
|
hasher.push(uDom.nodeFromId('no-remote-fonts').classList.contains('on'));
|
||||||
|
|
||||||
var hash = hasher.join('');
|
var hash = hasher.join('');
|
||||||
if ( reset ) {
|
if ( reset ) {
|
||||||
|
@ -301,7 +302,7 @@ var updateAllFirewallCells = function() {
|
||||||
|
|
||||||
positionRulesetTools();
|
positionRulesetTools();
|
||||||
|
|
||||||
uDom('#firewallContainer').toggleClass(
|
uDom.nodeFromId('firewallContainer').classList.toggle(
|
||||||
'dirty',
|
'dirty',
|
||||||
popupData.matrixIsDirty === true
|
popupData.matrixIsDirty === true
|
||||||
);
|
);
|
||||||
|
@ -385,7 +386,7 @@ var renderPrivacyExposure = function() {
|
||||||
|
|
||||||
var summary = domainsHitStr.replace('{{count}}', touchedDomainCount.toLocaleString())
|
var summary = domainsHitStr.replace('{{count}}', touchedDomainCount.toLocaleString())
|
||||||
.replace('{{total}}', allDomainCount.toLocaleString());
|
.replace('{{total}}', allDomainCount.toLocaleString());
|
||||||
uDom('#popupHitDomainCount').text(summary);
|
uDom.nodeFromId('popupHitDomainCount').textContent = summary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -397,8 +398,8 @@ var renderPopup = function() {
|
||||||
document.title = popupData.appName + ' - ' + popupData.tabTitle;
|
document.title = popupData.appName + ' - ' + popupData.tabTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
uDom('#appname').text(popupData.appName);
|
uDom.nodeFromId('appname').textContent = popupData.appName;
|
||||||
uDom('#version').text(popupData.appVersion);
|
uDom.nodeFromId('version').textContent = popupData.appVersion;
|
||||||
uDom('body')
|
uDom('body')
|
||||||
.toggleClass('advancedUser', popupData.advancedUserEnabled)
|
.toggleClass('advancedUser', popupData.advancedUserEnabled)
|
||||||
.toggleClass(
|
.toggleClass(
|
||||||
|
@ -409,7 +410,7 @@ var renderPopup = function() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you think the `=== true` is pointless, you are mistaken
|
// If you think the `=== true` is pointless, you are mistaken
|
||||||
uDom('#gotoPick').toggleClass('enabled', popupData.canElementPicker === true);
|
uDom.nodeFromId('gotoPick').classList.toggle('enabled', popupData.canElementPicker === true);
|
||||||
|
|
||||||
var text;
|
var text;
|
||||||
var blocked = popupData.pageBlockedRequestCount;
|
var blocked = popupData.pageBlockedRequestCount;
|
||||||
|
@ -420,7 +421,7 @@ var renderPopup = function() {
|
||||||
text = statsStr.replace('{{count}}', formatNumber(blocked))
|
text = statsStr.replace('{{count}}', formatNumber(blocked))
|
||||||
.replace('{{percent}}', formatNumber(Math.floor(blocked * 100 / total)));
|
.replace('{{percent}}', formatNumber(Math.floor(blocked * 100 / total)));
|
||||||
}
|
}
|
||||||
uDom('#page-blocked').text(text);
|
uDom.nodeFromId('page-blocked').textContent = text;
|
||||||
|
|
||||||
blocked = popupData.globalBlockedRequestCount;
|
blocked = popupData.globalBlockedRequestCount;
|
||||||
total = popupData.globalAllowedRequestCount + blocked;
|
total = popupData.globalAllowedRequestCount + blocked;
|
||||||
|
@ -430,15 +431,21 @@ var renderPopup = function() {
|
||||||
text = statsStr.replace('{{count}}', formatNumber(blocked))
|
text = statsStr.replace('{{count}}', formatNumber(blocked))
|
||||||
.replace('{{percent}}', formatNumber(Math.floor(blocked * 100 / total)));
|
.replace('{{percent}}', formatNumber(Math.floor(blocked * 100 / total)));
|
||||||
}
|
}
|
||||||
uDom('#total-blocked').text(text);
|
uDom.nodeFromId('total-blocked').textContent = text;
|
||||||
|
|
||||||
// This will collate all domains, touched or not
|
// This will collate all domains, touched or not
|
||||||
renderPrivacyExposure();
|
renderPrivacyExposure();
|
||||||
|
|
||||||
// Extra tools
|
// Extra tools
|
||||||
uDom('#no-popups').toggleClass('on', popupData.noPopups === true);
|
uDom.nodeFromId('no-popups').classList.toggle('on', popupData.noPopups === true);
|
||||||
uDom('#no-strict-blocking').toggleClass('on', popupData.noStrictBlocking === true);
|
uDom.nodeFromId('no-strict-blocking').classList.toggle('on', popupData.noStrictBlocking === true);
|
||||||
uDom('#no-cosmetic-filtering').toggleClass('on', popupData.noCosmeticFiltering === true);
|
uDom.nodeFromId('no-cosmetic-filtering').classList.toggle('on', popupData.noCosmeticFiltering === true);
|
||||||
|
uDom.nodeFromId('no-remote-fonts').classList.toggle('on', popupData.noRemoteFonts === true);
|
||||||
|
|
||||||
|
// Report remote font count on badge
|
||||||
|
total = popupData.remoteFontCount;
|
||||||
|
uDom.nodeFromSelector('#no-remote-fonts > span.badge')
|
||||||
|
.textContent = total ? total.toLocaleString() : '';
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/470
|
// https://github.com/chrisaljoudi/uBlock/issues/470
|
||||||
// This must be done here, to be sure the popup is resized properly
|
// This must be done here, to be sure the popup is resized properly
|
||||||
|
@ -453,7 +460,7 @@ var renderPopup = function() {
|
||||||
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
|
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
|
||||||
}
|
}
|
||||||
|
|
||||||
uDom('#panes').toggleClass('dfEnabled', dfPaneVisible);
|
uDom.nodeFromId('panes').classList.toggle('dfEnabled', dfPaneVisible);
|
||||||
uDom('#firewallContainer')
|
uDom('#firewallContainer')
|
||||||
.toggleClass('minimized', popupData.firewallPaneMinimized)
|
.toggleClass('minimized', popupData.firewallPaneMinimized)
|
||||||
.toggleClass('colorBlind', popupData.colorBlindFriendly);
|
.toggleClass('colorBlind', popupData.colorBlindFriendly);
|
||||||
|
@ -469,9 +476,8 @@ var renderPopup = function() {
|
||||||
var renderPopupLazy = function() {
|
var renderPopupLazy = function() {
|
||||||
var onDataReady = function(data) {
|
var onDataReady = function(data) {
|
||||||
var v = data.hiddenElementCount || '';
|
var v = data.hiddenElementCount || '';
|
||||||
uDom('#no-cosmetic-filtering > span.badge').text(
|
uDom.nodeFromSelector('#no-cosmetic-filtering > span.badge')
|
||||||
typeof v === 'number' ? v.toLocaleString() : v
|
.textContent = typeof v === 'number' ? v.toLocaleString() : v;
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
messager.send({
|
messager.send({
|
||||||
|
@ -554,7 +560,7 @@ var toggleFirewallPane = function() {
|
||||||
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
|
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
|
||||||
|
|
||||||
// Dynamic filtering pane may not have been built yet
|
// Dynamic filtering pane may not have been built yet
|
||||||
uDom('#panes').toggleClass('dfEnabled', popupData.dfEnabled);
|
uDom.nodeFromId('panes').classList.toggle('dfEnabled', popupData.dfEnabled);
|
||||||
if ( popupData.dfEnabled && dfPaneBuilt === false ) {
|
if ( popupData.dfEnabled && dfPaneBuilt === false ) {
|
||||||
buildAllFirewallRows();
|
buildAllFirewallRows();
|
||||||
}
|
}
|
||||||
|
@ -656,9 +662,9 @@ var reloadTab = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var toggleMinimize = function() {
|
var toggleMinimize = function() {
|
||||||
var elem = uDom('#firewallContainer');
|
popupData.firewallPaneMinimized = uDom.nodeFromId('firewallContainer')
|
||||||
elem.toggleClass('minimized');
|
.classList
|
||||||
popupData.firewallPaneMinimized = elem.hasClass('minimized');
|
.toggle('minimized');
|
||||||
messager.send({
|
messager.send({
|
||||||
what: 'userSettings',
|
what: 'userSettings',
|
||||||
name: 'firewallPaneMinimized',
|
name: 'firewallPaneMinimized',
|
||||||
|
@ -675,7 +681,7 @@ var saveFirewallRules = function() {
|
||||||
srcHostname: popupData.pageHostname,
|
srcHostname: popupData.pageHostname,
|
||||||
desHostnames: popupData.hostnameDict
|
desHostnames: popupData.hostnameDict
|
||||||
});
|
});
|
||||||
uDom('#firewallContainer').removeClass('dirty');
|
uDom.nodeFromId('firewallContainer').classList.remove('dirty');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -692,7 +698,7 @@ var revertFirewallRules = function() {
|
||||||
desHostnames: popupData.hostnameDict,
|
desHostnames: popupData.hostnameDict,
|
||||||
tabId: popupData.tabId
|
tabId: popupData.tabId
|
||||||
}, onFirewallRuleChanged);
|
}, onFirewallRuleChanged);
|
||||||
uDom('#firewallContainer').removeClass('dirty');
|
uDom.nodeFromId('firewallContainer').classList.remove('dirty');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -810,7 +816,7 @@ var onShowTooltip = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var onHideTooltip = function() {
|
var onHideTooltip = function() {
|
||||||
uDom('#tooltip').removeClass('show');
|
uDom.nodeFromId('tooltip').classList.remove('show');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<span id="no-popups" class="hnSwitch fa" data-i18n-tip="popupTipNoPopups"><span></span></span>
|
<span id="no-popups" class="hnSwitch fa" data-i18n-tip="popupTipNoPopups"><span></span></span>
|
||||||
<span id="no-strict-blocking" class="hnSwitch fa" data-i18n-tip="popupTipNoStrictBlocking"><span></span></span>
|
<span id="no-strict-blocking" class="hnSwitch fa" data-i18n-tip="popupTipNoStrictBlocking"><span></span></span>
|
||||||
<span id="no-cosmetic-filtering" class="hnSwitch fa" data-i18n-tip="popupTipNoCosmeticFiltering"><span class="badge"></span><span></span></span>
|
<span id="no-cosmetic-filtering" class="hnSwitch fa" data-i18n-tip="popupTipNoCosmeticFiltering"><span class="badge"></span><span></span></span>
|
||||||
|
<span id="no-remote-fonts" class="hnSwitch fa" data-i18n-tip="popupTipNoRemoteFonts"><span class="badge"></span><span></span></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="refresh" class="fa"></div>
|
<div id="refresh" class="fa"></div>
|
||||||
<div id="tooltip"></div>
|
<div id="tooltip"></div>
|
||||||
|
|
Loading…
Reference in New Issue