1
0
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:
gorhill 2015-09-27 10:13:31 -04:00
parent e62246b380
commit 12baeadac4
2 changed files with 73 additions and 17 deletions

View File

@ -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.
} }

View File

@ -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
}; };