mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-15 15:32:28 +02:00
Fine tune latest changes for performance
Related commits: -157cef6034
-1e2eb037e5
This commit is contained in:
parent
04b02f8044
commit
19331f1ab5
@ -1666,23 +1666,26 @@ const FilterCompositeAll = class extends FilterCollection {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IMPORTANT: the modifier filter unit is assumed to be ALWAYS the
|
||||||
|
// first unit in the sequence. This requirement ensures that we do
|
||||||
|
// not have to traverse the sequence to find the modifier filter
|
||||||
|
// unit.
|
||||||
matchAndFetchModifiers(env) {
|
matchAndFetchModifiers(env) {
|
||||||
if ( this.match() !== true ) { return false; }
|
const f = filterUnits[filterSequences[this.i]];
|
||||||
this.forEach(iunit => {
|
if (
|
||||||
const f = filterUnits[iunit];
|
f.matchAndFetchModifiers instanceof Function &&
|
||||||
if ( f.matchAndFetchModifiers instanceof Function ) {
|
f.type === env.modifier &&
|
||||||
f.matchAndFetchModifiers(env);
|
this.match()
|
||||||
}
|
) {
|
||||||
});
|
f.matchAndFetchModifiers(env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get modifier() {
|
get modifier() {
|
||||||
return this.forEach(iunit => {
|
const f = filterUnits[filterSequences[this.i]];
|
||||||
const f = filterUnits[iunit];
|
if ( f.matchAndFetchModifiers instanceof Function ) {
|
||||||
if ( f.matchAndFetchModifiers instanceof Function ) {
|
return f.modifier;
|
||||||
return f.modifier;
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterPatternPlain is assumed to be first filter in sequence. This can
|
// FilterPatternPlain is assumed to be first filter in sequence. This can
|
||||||
@ -1985,11 +1988,14 @@ const FilterBucket = class extends FilterCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
matchAndFetchModifiers(env) {
|
matchAndFetchModifiers(env) {
|
||||||
|
const sequences = filterSequences;
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
this.forEach(iunit => {
|
let i = this.i;
|
||||||
env.iunit = iunit;
|
while ( i !== 0 ) {
|
||||||
units[iunit].matchAndFetchModifiers(env);
|
env.iunit = sequences[i+0];
|
||||||
});
|
units[env.iunit].matchAndFetchModifiers(env);
|
||||||
|
i = sequences[i+1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logData(details) {
|
logData(details) {
|
||||||
@ -2401,6 +2407,7 @@ const FilterParser = class {
|
|||||||
this.modifyValue = 'noopmp4-1s';
|
this.modifyValue = 'noopmp4-1s';
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenQueryprune:
|
case parser.OPTTokenQueryprune:
|
||||||
|
// TODO: validate value
|
||||||
case parser.OPTTokenRedirect:
|
case parser.OPTTokenRedirect:
|
||||||
case parser.OPTTokenRedirectRule:
|
case parser.OPTTokenRedirectRule:
|
||||||
if ( this.modifyType !== undefined ) { return false; }
|
if ( this.modifyType !== undefined ) { return false; }
|
||||||
@ -3083,8 +3090,11 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Modifier
|
// Modifier
|
||||||
|
//
|
||||||
|
// IMPORTANT: the modifier unit MUST always appear first in a sequence.
|
||||||
|
//
|
||||||
|
// Reminder: A block filter is implicit with `redirect=` modifier.
|
||||||
if ( parsed.modifyType !== undefined ) {
|
if ( parsed.modifyType !== undefined ) {
|
||||||
// A block filter is implicit with `redirect=` modifier
|
|
||||||
if (
|
if (
|
||||||
parsed.modifyType === parser.OPTTokenRedirect &&
|
parsed.modifyType === parser.OPTTokenRedirect &&
|
||||||
(parsed.action & ActionBitsMask) !== AllowAction
|
(parsed.action & ActionBitsMask) !== AllowAction
|
||||||
@ -3096,7 +3106,7 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
);
|
);
|
||||||
parsed.modifyType = parser.OPTTokenRedirectRule;
|
parsed.modifyType = parser.OPTTokenRedirectRule;
|
||||||
}
|
}
|
||||||
units.push(FilterModifier.compile(parsed));
|
units.unshift(FilterModifier.compile(parsed));
|
||||||
parsed.action = ModifyAction;
|
parsed.action = ModifyAction;
|
||||||
parsed.important = 0;
|
parsed.important = 0;
|
||||||
}
|
}
|
||||||
@ -3202,13 +3212,13 @@ FilterContainer.prototype.matchAndFetchModifiers = function(
|
|||||||
? this.categories.get(catBits11)
|
? this.categories.get(catBits11)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const modifierResults = [];
|
const results = [];
|
||||||
const env = {
|
const env = {
|
||||||
modifier: vAPI.StaticFilteringParser.netOptionTokenIds.get(modifierType) || 0,
|
modifier: vAPI.StaticFilteringParser.netOptionTokenIds.get(modifierType) || 0,
|
||||||
bits: 0,
|
bits: 0,
|
||||||
th: 0,
|
th: 0,
|
||||||
iunit: 0,
|
iunit: 0,
|
||||||
results: modifierResults,
|
results,
|
||||||
};
|
};
|
||||||
|
|
||||||
const units = filterUnits;
|
const units = filterUnits;
|
||||||
@ -3250,36 +3260,60 @@ FilterContainer.prototype.matchAndFetchModifiers = function(
|
|||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( modifierResults.length === 0 ) { return; }
|
if ( results.length === 0 ) { return; }
|
||||||
|
|
||||||
|
// One single result is expected to be a common occurrence, and in such
|
||||||
|
// case there is no need to process exception vs. block, block important
|
||||||
|
// occurrences.
|
||||||
|
if ( results.length === 1 ) {
|
||||||
|
const result = results[0];
|
||||||
|
if ( (result.bits & ActionBitsMask) === AllowAction ) { return; }
|
||||||
|
return [ result ];
|
||||||
|
}
|
||||||
|
|
||||||
const toAddImportant = new Map();
|
const toAddImportant = new Map();
|
||||||
const toAdd = new Map();
|
const toAdd = new Map();
|
||||||
const toRemove = new Map();
|
const toRemove = new Map();
|
||||||
|
|
||||||
for ( const modifierResult of modifierResults ) {
|
for ( const result of results ) {
|
||||||
const actionBits = modifierResult.bits & ActionBitsMask;
|
const actionBits = result.bits & ActionBitsMask;
|
||||||
const modifyValue = modifierResult.modifier.value;
|
const modifyValue = result.modifier.value;
|
||||||
if ( actionBits === BlockImportant ) {
|
if ( actionBits === BlockImportant ) {
|
||||||
toAddImportant.set(modifyValue, modifierResult);
|
toAddImportant.set(modifyValue, result);
|
||||||
} else if ( actionBits === BlockAction ) {
|
} else if ( actionBits === BlockAction ) {
|
||||||
toAdd.set(modifyValue, modifierResult);
|
toAdd.set(modifyValue, result);
|
||||||
} else {
|
} else {
|
||||||
toRemove.set(modifyValue, modifierResult);
|
toRemove.set(modifyValue, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( toAddImportant.size === 0 && toAdd.size === 0 ) { return; }
|
if ( toAddImportant.size === 0 && toAdd.size === 0 ) { return; }
|
||||||
|
|
||||||
// Remove entries overriden by important block filters.
|
// Remove entries overriden by important block filters.
|
||||||
for ( const key of toAddImportant.keys() ) {
|
if ( toAddImportant.size !== 0 ) {
|
||||||
toAdd.delete(key);
|
for ( const key of toAddImportant.keys() ) {
|
||||||
toRemove.delete(key);
|
toAdd.delete(key);
|
||||||
|
toRemove.delete(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exception filters
|
||||||
|
//
|
||||||
|
// Remove excepted block filters and unused exception filters.
|
||||||
|
//
|
||||||
// Special case, except-all:
|
// Special case, except-all:
|
||||||
// - Except-all applies only if there is at least one normal block filters.
|
// - Except-all applies only if there is at least one normal block filters.
|
||||||
// - Except-all does not apply to important block filters.
|
// - Except-all does not apply to important block filters.
|
||||||
if ( toRemove.has('') ) {
|
if ( toRemove.size !== 0 ) {
|
||||||
if ( toAdd.size !== 0 ) {
|
if ( toRemove.has('') === false ) {
|
||||||
|
for ( const key of toRemove.keys() ) {
|
||||||
|
if ( toAdd.has(key) ) {
|
||||||
|
toAdd.delete(key);
|
||||||
|
} else {
|
||||||
|
toRemove.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( toAdd.size !== 0 ) {
|
||||||
toAdd.clear();
|
toAdd.clear();
|
||||||
if ( toRemove.size !== 1 ) {
|
if ( toRemove.size !== 1 ) {
|
||||||
const entry = toRemove.get('');
|
const entry = toRemove.get('');
|
||||||
@ -3290,16 +3324,6 @@ FilterContainer.prototype.matchAndFetchModifiers = function(
|
|||||||
toRemove.clear();
|
toRemove.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove excepted block filters and unused exception filters.
|
|
||||||
else {
|
|
||||||
for ( const key of toRemove.keys() ) {
|
|
||||||
if ( toAdd.has(key) ) {
|
|
||||||
toAdd.delete(key);
|
|
||||||
} else {
|
|
||||||
toRemove.delete(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
toAdd.size === 0 &&
|
toAdd.size === 0 &&
|
||||||
@ -3525,7 +3549,25 @@ FilterContainer.prototype.matchString = function(fctxt, modifiers = 0) {
|
|||||||
|
|
||||||
FilterContainer.prototype.redirectRequest = function(fctxt) {
|
FilterContainer.prototype.redirectRequest = function(fctxt) {
|
||||||
const directives = this.matchAndFetchModifiers(fctxt, 'redirect-rule');
|
const directives = this.matchAndFetchModifiers(fctxt, 'redirect-rule');
|
||||||
|
// No directive is the most common occurrence.
|
||||||
if ( directives === undefined ) { return; }
|
if ( directives === undefined ) { return; }
|
||||||
|
// A single directive should be the next most common occurrence.
|
||||||
|
if ( directives.length === 1 ) {
|
||||||
|
const directive = directives[0];
|
||||||
|
if ( (directive.bits & ActionBitsMask) === AllowAction ) {
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
const modifier = directive.modifier;
|
||||||
|
if ( modifier.cache === undefined ) {
|
||||||
|
modifier.cache = this.parseRedirectRequestValue(modifier.value);
|
||||||
|
}
|
||||||
|
fctxt.redirectURL = µb.redirectEngine.tokenToURL(
|
||||||
|
fctxt,
|
||||||
|
modifier.cache.token
|
||||||
|
);
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
// Multiple directives mean more work to do.
|
||||||
let winningDirective;
|
let winningDirective;
|
||||||
let winningPriority = 0;
|
let winningPriority = 0;
|
||||||
for ( const directive of directives ) {
|
for ( const directive of directives ) {
|
||||||
@ -3536,15 +3578,7 @@ FilterContainer.prototype.redirectRequest = function(fctxt) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( modifier.cache === undefined ) {
|
if ( modifier.cache === undefined ) {
|
||||||
const rawToken = modifier.value;
|
modifier.cache = this.parseRedirectRequestValue(modifier.value);
|
||||||
let token = rawToken;
|
|
||||||
let priority = 0;
|
|
||||||
const match = /:(\d+)$/.exec(rawToken);
|
|
||||||
if ( match !== null ) {
|
|
||||||
token = rawToken.slice(0, match.index);
|
|
||||||
priority = parseInt(match[1], 10);
|
|
||||||
}
|
|
||||||
modifier.cache = { token, priority };
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
winningDirective === undefined ||
|
winningDirective === undefined ||
|
||||||
@ -3564,9 +3598,15 @@ FilterContainer.prototype.redirectRequest = function(fctxt) {
|
|||||||
return winningDirective;
|
return winningDirective;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterContainer.prototype.hasQuery = function(fctxt) {
|
FilterContainer.prototype.parseRedirectRequestValue = function(rawValue) {
|
||||||
urlTokenizer.setURL(fctxt.url);
|
let token = rawValue;
|
||||||
return urlTokenizer.hasQuery();
|
let priority = 0;
|
||||||
|
const match = /:(\d+)$/.exec(rawValue);
|
||||||
|
if ( match !== null ) {
|
||||||
|
token = rawValue.slice(0, match.index);
|
||||||
|
priority = parseInt(match[1], 10);
|
||||||
|
}
|
||||||
|
return { token, priority };
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -3587,10 +3627,7 @@ FilterContainer.prototype.filterQuery = function(fctxt) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( modifier.cache === undefined ) {
|
if ( modifier.cache === undefined ) {
|
||||||
let retext = modifier.value;
|
modifier.cache = this.parseFilterPruneValue(modifier.value);
|
||||||
if ( retext.startsWith('|') ) { retext = `^${retext.slice(1)}`; }
|
|
||||||
if ( retext.endsWith('|') ) { retext = `${retext.slice(0,-1)}$`; }
|
|
||||||
modifier.cache = new RegExp(retext);
|
|
||||||
}
|
}
|
||||||
const re = modifier.cache;
|
const re = modifier.cache;
|
||||||
let filtered = false;
|
let filtered = false;
|
||||||
@ -3615,6 +3652,19 @@ FilterContainer.prototype.filterQuery = function(fctxt) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterContainer.prototype.parseFilterPruneValue = function(rawValue) {
|
||||||
|
let retext = rawValue;
|
||||||
|
if ( retext.startsWith('|') ) { retext = `^${retext.slice(1)}`; }
|
||||||
|
if ( retext.endsWith('|') ) { retext = `${retext.slice(0,-1)}$`; }
|
||||||
|
try {
|
||||||
|
return new RegExp(retext);
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
|
return /.^/;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.hasQuery = function(fctxt) {
|
FilterContainer.prototype.hasQuery = function(fctxt) {
|
||||||
urlTokenizer.setURL(fctxt.url);
|
urlTokenizer.setURL(fctxt.url);
|
||||||
return urlTokenizer.hasQuery();
|
return urlTokenizer.hasQuery();
|
||||||
|
Loading…
Reference in New Issue
Block a user