mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-15 07:22:28 +02:00
code review of new script tag filtering code
This commit is contained in:
parent
e62246b380
commit
12baeadac4
@ -74,7 +74,6 @@ var localMessager = vAPI.messaging.channel('contentscript-start.js');
|
|||||||
var cosmeticFilters = function(details) {
|
var cosmeticFilters = function(details) {
|
||||||
var donthideCosmeticFilters = {};
|
var donthideCosmeticFilters = {};
|
||||||
var hideCosmeticFilters = {};
|
var hideCosmeticFilters = {};
|
||||||
var scriptTagFilters = [];
|
|
||||||
var donthide = details.cosmeticDonthide;
|
var donthide = details.cosmeticDonthide;
|
||||||
var hide = details.cosmeticHide;
|
var hide = details.cosmeticHide;
|
||||||
var i;
|
var i;
|
||||||
@ -92,14 +91,9 @@ var cosmeticFilters = function(details) {
|
|||||||
selector = hide[i];
|
selector = hide[i];
|
||||||
if ( donthideCosmeticFilters[selector] ) {
|
if ( donthideCosmeticFilters[selector] ) {
|
||||||
hide.splice(i, 1);
|
hide.splice(i, 1);
|
||||||
continue;
|
} else {
|
||||||
|
hideCosmeticFilters[selector] = true;
|
||||||
}
|
}
|
||||||
if ( selector.lastIndexOf('script//:', 0) === 0 ) {
|
|
||||||
scriptTagFilters.push(selector.slice(9));
|
|
||||||
hide.splice(i, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hideCosmeticFilters[selector] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( hide.length !== 0 ) {
|
if ( hide.length !== 0 ) {
|
||||||
@ -117,11 +111,6 @@ var cosmeticFilters = function(details) {
|
|||||||
}
|
}
|
||||||
vAPI.donthideCosmeticFilters = donthideCosmeticFilters;
|
vAPI.donthideCosmeticFilters = donthideCosmeticFilters;
|
||||||
vAPI.hideCosmeticFilters = hideCosmeticFilters;
|
vAPI.hideCosmeticFilters = hideCosmeticFilters;
|
||||||
|
|
||||||
if ( scriptTagFilters.length !== 0 ) {
|
|
||||||
vAPI.reScriptTagFilters = new RegExp(scriptTagFilters.join('|'));
|
|
||||||
document.addEventListener('beforescriptexecute', onBeforeScriptExecuteHandler);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var netFilters = function(details) {
|
var netFilters = function(details) {
|
||||||
@ -140,13 +129,14 @@ var netFilters = function(details) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var onBeforeScriptExecuteHandler = function(ev) {
|
var onBeforeScriptExecuteHandler = function(ev) {
|
||||||
if ( vAPI.reScriptTagFilters.test(ev.target.textContent) ) {
|
if ( vAPI.reScriptTagRegex.test(ev.target.textContent) ) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var filteringHandler = function(details) {
|
var filteringHandler = function(details) {
|
||||||
|
var value;
|
||||||
var styleTagCount = vAPI.styles.length;
|
var styleTagCount = vAPI.styles.length;
|
||||||
|
|
||||||
vAPI.skipCosmeticFiltering = !details || details.skipCosmeticFiltering;
|
vAPI.skipCosmeticFiltering = !details || details.skipCosmeticFiltering;
|
||||||
@ -157,6 +147,11 @@ var filteringHandler = function(details) {
|
|||||||
if ( details.netHide.length !== 0 ) {
|
if ( details.netHide.length !== 0 ) {
|
||||||
netFilters(details);
|
netFilters(details);
|
||||||
}
|
}
|
||||||
|
value = details.scriptTagRegex;
|
||||||
|
if ( typeof value === 'string' && value.length !== 0 ) {
|
||||||
|
vAPI.reScriptTagRegex = new RegExp(value);
|
||||||
|
document.addEventListener('beforescriptexecute', onBeforeScriptExecuteHandler);
|
||||||
|
}
|
||||||
// The port will never be used again at this point, disconnecting allows
|
// The port will never be used again at this point, disconnecting allows
|
||||||
// the browser to flush this script from memory.
|
// the browser to flush this script from memory.
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,7 @@ var FilterParser = function() {
|
|||||||
this.invalid = false;
|
this.invalid = false;
|
||||||
this.cosmetic = true;
|
this.cosmetic = true;
|
||||||
this.reParser = /^\s*([^#]*)(##|#@#)(.+)\s*$/;
|
this.reParser = /^\s*([^#]*)(##|#@#)(.+)\s*$/;
|
||||||
|
this.reScriptSelectorParser = /^script:contains\(\/.+?\/\)$/;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -286,8 +287,8 @@ FilterParser.prototype.parse = function(s) {
|
|||||||
// Script tag filters: pre-process them so that can be used with minimal
|
// Script tag filters: pre-process them so that can be used with minimal
|
||||||
// overhead in the content script.
|
// overhead in the content script.
|
||||||
if (
|
if (
|
||||||
this.suffix.lastIndexOf('script:contains(/', 0) === 0 &&
|
this.suffix.charAt(0) === 's' &&
|
||||||
this.suffix.slice(-2) === '/)'
|
this.reScriptSelectorParser.test(this.suffix)
|
||||||
) {
|
) {
|
||||||
// Currently supported only as non-generic selector.
|
// Currently supported only as non-generic selector.
|
||||||
if ( this.prefix.length === 0 ) {
|
if ( this.prefix.length === 0 ) {
|
||||||
@ -568,6 +569,8 @@ FilterContainer.prototype.reset = function() {
|
|||||||
// hostname, entity-based filters
|
// hostname, entity-based filters
|
||||||
this.hostnameFilters = {};
|
this.hostnameFilters = {};
|
||||||
this.entityFilters = {};
|
this.entityFilters = {};
|
||||||
|
this.scriptTagFilters = {};
|
||||||
|
this.scriptTagFilterCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -807,6 +810,11 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||||||
|
|
||||||
// h ir twitter.com .promoted-tweet
|
// h ir twitter.com .promoted-tweet
|
||||||
if ( fields[0] === 'h' ) {
|
if ( fields[0] === 'h' ) {
|
||||||
|
// Special filter: script tags. Not a real CSS selector.
|
||||||
|
if ( fields[3].lastIndexOf('script//:', 0) === 0 ) {
|
||||||
|
this.createScriptTagFilter(fields[2], fields[3].slice(9));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
filter = new FilterHostname(fields[3], fields[2]);
|
filter = new FilterHostname(fields[3], fields[2]);
|
||||||
bucket = this.hostnameFilters[fields[1]];
|
bucket = this.hostnameFilters[fields[1]];
|
||||||
if ( bucket === undefined ) {
|
if ( bucket === undefined ) {
|
||||||
@ -838,6 +846,11 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||||||
|
|
||||||
// entity selector
|
// entity selector
|
||||||
if ( fields[0] === 'e' ) {
|
if ( fields[0] === 'e' ) {
|
||||||
|
// Special filter: script tags. Not a real CSS selector.
|
||||||
|
if ( fields[2].lastIndexOf('script//:', 0) === 0 ) {
|
||||||
|
this.createScriptTagFilter(fields[1], fields[2].slice(9));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
bucket = this.entityFilters[fields[1]];
|
bucket = this.entityFilters[fields[1]];
|
||||||
if ( bucket === undefined ) {
|
if ( bucket === undefined ) {
|
||||||
this.entityFilters[fields[1]] = [fields[2]];
|
this.entityFilters[fields[1]] = [fields[2]];
|
||||||
@ -903,6 +916,49 @@ FilterContainer.prototype.skipCompiledContent = function(text, lineBeg) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
FilterContainer.prototype.createScriptTagFilter = function(hostname, s) {
|
||||||
|
if ( this.scriptTagFilters.hasOwnProperty(hostname) ) {
|
||||||
|
this.scriptTagFilters[hostname] += '|' + s;
|
||||||
|
} else {
|
||||||
|
this.scriptTagFilters[hostname] = s;
|
||||||
|
}
|
||||||
|
this.scriptTagFilterCount += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
FilterContainer.prototype.retrieveScriptTagRegex = function(domain, hostname) {
|
||||||
|
if ( this.scriptTagFilterCount === 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var out = [], hn = hostname, pos;
|
||||||
|
for (;;) {
|
||||||
|
if ( this.scriptTagFilters.hasOwnProperty(hn) ) {
|
||||||
|
out.push(this.scriptTagFilters[hn]);
|
||||||
|
}
|
||||||
|
if ( hn === domain ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = hn.indexOf('.');
|
||||||
|
if ( pos === -1 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hn = hn.slice(pos + 1);
|
||||||
|
}
|
||||||
|
pos = domain.indexOf('.');
|
||||||
|
if ( pos !== -1 ) {
|
||||||
|
hn = domain.slice(0, pos);
|
||||||
|
if ( this.scriptTagFilters.hasOwnProperty(hn) ) {
|
||||||
|
out.push(this.scriptTagFilters[hn]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( out.length !== 0 ) {
|
||||||
|
return out.join('|');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.freeze = function() {
|
FilterContainer.prototype.freeze = function() {
|
||||||
this.duplicateBuster = {};
|
this.duplicateBuster = {};
|
||||||
|
|
||||||
@ -956,7 +1012,9 @@ FilterContainer.prototype.toSelfie = function() {
|
|||||||
highMediumGenericHideCount: this.highMediumGenericHideCount,
|
highMediumGenericHideCount: this.highMediumGenericHideCount,
|
||||||
highHighGenericHide: this.highHighGenericHide,
|
highHighGenericHide: this.highHighGenericHide,
|
||||||
highHighGenericHideCount: this.highHighGenericHideCount,
|
highHighGenericHideCount: this.highHighGenericHideCount,
|
||||||
genericDonthide: this.genericDonthide
|
genericDonthide: this.genericDonthide,
|
||||||
|
scriptTagFilters: this.scriptTagFilters,
|
||||||
|
scriptTagFilterCount: this.scriptTagFilterCount
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1017,6 +1075,8 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
|
|||||||
this.highHighGenericHide = selfie.highHighGenericHide;
|
this.highHighGenericHide = selfie.highHighGenericHide;
|
||||||
this.highHighGenericHideCount = selfie.highHighGenericHideCount;
|
this.highHighGenericHideCount = selfie.highHighGenericHideCount;
|
||||||
this.genericDonthide = selfie.genericDonthide;
|
this.genericDonthide = selfie.genericDonthide;
|
||||||
|
this.scriptTagFilters = selfie.scriptTagFilters;
|
||||||
|
this.scriptTagFilterCount = selfie.scriptTagFilterCount;
|
||||||
this.frozen = true;
|
this.frozen = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1197,6 +1257,7 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request) {
|
|||||||
cosmeticHide: [],
|
cosmeticHide: [],
|
||||||
cosmeticDonthide: [],
|
cosmeticDonthide: [],
|
||||||
netHide: [],
|
netHide: [],
|
||||||
|
scriptTagRegex: this.retrieveScriptTagRegex(domain, hostname),
|
||||||
netCollapse: µb.userSettings.collapseBlocked
|
netCollapse: µb.userSettings.collapseBlocked
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user