this fixes #191 completely

This commit is contained in:
gorhill 2014-08-28 09:59:05 -04:00
parent 527817d2f2
commit fe2d761908

View file

@ -41,6 +41,7 @@
const BlockAction = 0 << 15; const BlockAction = 0 << 15;
const AllowAction = 1 << 15; const AllowAction = 1 << 15;
const ToggleAction = BlockAction ^ AllowAction;
const AnyType = 1 << 11; const AnyType = 1 << 11;
@ -209,6 +210,12 @@ FilterPlain.prototype.match = function(url, tokenBeg) {
return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s; return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
}; };
FilterPlain.prototype.toString = function() {
return this.s;
};
/******************************************************************************/
var FilterPlainHostname = function(s, tokenBeg, hostname) { var FilterPlainHostname = function(s, tokenBeg, hostname) {
this.s = s; this.s = s;
this.tokenBeg = tokenBeg; this.tokenBeg = tokenBeg;
@ -221,6 +228,10 @@ FilterPlainHostname.prototype.match = function(url, tokenBeg) {
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s; url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
}; };
FilterPlainHostname.prototype.toString = function() {
return this.s + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var FilterPlainPrefix0 = function(s) { var FilterPlainPrefix0 = function(s) {
@ -232,6 +243,12 @@ FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
return url.substr(tokenBeg, this.s.length) === this.s; return url.substr(tokenBeg, this.s.length) === this.s;
}; };
FilterPlainPrefix0.prototype.toString = function() {
return this.s;
};
/******************************************************************************/
var FilterPlainPrefix0Hostname = function(s, hostname) { var FilterPlainPrefix0Hostname = function(s, hostname) {
this.s = s; this.s = s;
this.hostname = hostname; this.hostname = hostname;
@ -243,6 +260,10 @@ FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
url.substr(tokenBeg, this.s.length) === this.s; url.substr(tokenBeg, this.s.length) === this.s;
}; };
FilterPlainPrefix0Hostname.prototype.toString = function() {
return this.s + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var FilterPlainPrefix1 = function(s) { var FilterPlainPrefix1 = function(s) {
@ -254,6 +275,12 @@ FilterPlainPrefix1.prototype.match = function(url, tokenBeg) {
return url.substr(tokenBeg - 1, this.s.length) === this.s; return url.substr(tokenBeg - 1, this.s.length) === this.s;
}; };
FilterPlainPrefix1.prototype.toString = function() {
return this.s;
};
/******************************************************************************/
var FilterPlainPrefix1Hostname = function(s, hostname) { var FilterPlainPrefix1Hostname = function(s, hostname) {
this.s = s; this.s = s;
this.hostname = hostname; this.hostname = hostname;
@ -265,6 +292,10 @@ FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
url.substr(tokenBeg - 1, this.s.length) === this.s; url.substr(tokenBeg - 1, this.s.length) === this.s;
}; };
FilterPlainPrefix1Hostname.prototype.toString = function() {
return this.s + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var FilterPlainLeftAnchored = function(s) { var FilterPlainLeftAnchored = function(s) {
@ -276,6 +307,12 @@ FilterPlainLeftAnchored.prototype.match = function(url) {
return url.slice(0, this.s.length) === this.s; return url.slice(0, this.s.length) === this.s;
}; };
FilterPlainLeftAnchored.prototype.toString = function() {
return '|' + this.s;
};
/******************************************************************************/
var FilterPlainLeftAnchoredHostname = function(s, hostname) { var FilterPlainLeftAnchoredHostname = function(s, hostname) {
this.s = s; this.s = s;
this.hostname = hostname; this.hostname = hostname;
@ -287,6 +324,10 @@ FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
url.slice(0, this.s.length) === this.s; url.slice(0, this.s.length) === this.s;
}; };
FilterPlainLeftAnchoredHostname.prototype.toString = function() {
return '|' + this.s + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var FilterPlainRightAnchored = function(s) { var FilterPlainRightAnchored = function(s) {
@ -298,6 +339,12 @@ FilterPlainRightAnchored.prototype.match = function(url) {
return url.slice(-this.s.length) === this.s; return url.slice(-this.s.length) === this.s;
}; };
FilterPlainRightAnchored.prototype.toString = function() {
return this.s + '|';
};
/******************************************************************************/
var FilterPlainRightAnchoredHostname = function(s, hostname) { var FilterPlainRightAnchoredHostname = function(s, hostname) {
this.s = s; this.s = s;
this.hostname = hostname; this.hostname = hostname;
@ -309,6 +356,10 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
url.slice(-this.s.length) === this.s; url.slice(-this.s.length) === this.s;
}; };
FilterPlainRightAnchoredHostname.prototype.toString = function() {
return this.s + '|$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
// With a single wildcard, regex is not optimal. // With a single wildcard, regex is not optimal.
@ -317,7 +368,6 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
// http://jsperf.com/regexp-vs-indexof-abp-hit/3 // http://jsperf.com/regexp-vs-indexof-abp-hit/3
var FilterSingleWildcard = function(s, tokenBeg) { var FilterSingleWildcard = function(s, tokenBeg) {
this.s = s;
this.tokenBeg = tokenBeg; this.tokenBeg = tokenBeg;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
@ -331,8 +381,13 @@ FilterSingleWildcard.prototype.match = function(url, tokenBeg) {
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0; url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
}; };
FilterSingleWildcard.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment;
};
/******************************************************************************/
var FilterSingleWildcardHostname = function(s, tokenBeg, hostname) { var FilterSingleWildcardHostname = function(s, tokenBeg, hostname) {
this.s = s;
this.tokenBeg = tokenBeg; this.tokenBeg = tokenBeg;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
@ -348,10 +403,13 @@ FilterSingleWildcardHostname.prototype.match = function(url, tokenBeg) {
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0; url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
}; };
FilterSingleWildcardHostname.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var FilterSingleWildcardPrefix0 = function(s) { var FilterSingleWildcardPrefix0 = function(s) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -363,8 +421,13 @@ FilterSingleWildcardPrefix0.prototype.match = function(url, tokenBeg) {
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0; url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
}; };
FilterSingleWildcardPrefix0.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment;
};
/******************************************************************************/
var FilterSingleWildcardPrefix0Hostname = function(s, hostname) { var FilterSingleWildcardPrefix0Hostname = function(s, hostname) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -378,6 +441,10 @@ FilterSingleWildcardPrefix0Hostname.prototype.match = function(url, tokenBeg) {
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0; url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
}; };
FilterSingleWildcardPrefix0Hostname.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
// With a single wildcard, regex is not optimal. // With a single wildcard, regex is not optimal.
@ -386,7 +453,6 @@ FilterSingleWildcardPrefix0Hostname.prototype.match = function(url, tokenBeg) {
// http://jsperf.com/regexp-vs-indexof-abp-hit/3 // http://jsperf.com/regexp-vs-indexof-abp-hit/3
var FilterSingleWildcardLeftAnchored = function(s) { var FilterSingleWildcardLeftAnchored = function(s) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -398,8 +464,13 @@ FilterSingleWildcardLeftAnchored.prototype.match = function(url) {
url.indexOf(this.rSegment, this.lSegment.length) > 0; url.indexOf(this.rSegment, this.lSegment.length) > 0;
}; };
FilterSingleWildcardLeftAnchored.prototype.toString = function() {
return '|' + this.lSegment + '*' + this.rSegment;
};
/******************************************************************************/
var FilterSingleWildcardLeftAnchoredHostname = function(s, hostname) { var FilterSingleWildcardLeftAnchoredHostname = function(s, hostname) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -413,6 +484,10 @@ FilterSingleWildcardLeftAnchoredHostname.prototype.match = function(url) {
url.indexOf(this.rSegment, this.lSegment.length) > 0; url.indexOf(this.rSegment, this.lSegment.length) > 0;
}; };
FilterSingleWildcardLeftAnchoredHostname.prototype.toString = function() {
return '|' + this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
// With a single wildcard, regex is not optimal. // With a single wildcard, regex is not optimal.
@ -421,7 +496,6 @@ FilterSingleWildcardLeftAnchoredHostname.prototype.match = function(url) {
// http://jsperf.com/regexp-vs-indexof-abp-hit/3 // http://jsperf.com/regexp-vs-indexof-abp-hit/3
var FilterSingleWildcardRightAnchored = function(s) { var FilterSingleWildcardRightAnchored = function(s) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -433,8 +507,13 @@ FilterSingleWildcardRightAnchored.prototype.match = function(url) {
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0; url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
}; };
FilterSingleWildcardRightAnchored.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment + '|';
};
/******************************************************************************/
var FilterSingleWildcardRightAnchoredHostname = function(s, hostname) { var FilterSingleWildcardRightAnchoredHostname = function(s, hostname) {
this.s = s;
var wcOffset = s.indexOf('*'); var wcOffset = s.indexOf('*');
this.lSegment = s.slice(0, wcOffset); this.lSegment = s.slice(0, wcOffset);
this.rSegment = s.slice(wcOffset + 1); this.rSegment = s.slice(wcOffset + 1);
@ -448,6 +527,10 @@ FilterSingleWildcardRightAnchoredHostname.prototype.match = function(url) {
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0; url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
}; };
FilterSingleWildcardRightAnchoredHostname.prototype.toString = function() {
return this.lSegment + '*' + this.rSegment + '|$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
// With many wildcards, a regex is best. // With many wildcards, a regex is best.
@ -467,6 +550,12 @@ FilterManyWildcards.prototype.match = function(url, tokenBeg) {
return this.re.test(url.slice(tokenBeg - this.tokenBeg)); return this.re.test(url.slice(tokenBeg - this.tokenBeg));
}; };
FilterManyWildcards.prototype.toString = function() {
return this.s;
};
/******************************************************************************/
var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) { var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) {
this.s = s; this.s = s;
this.tokenBeg = tokenBeg; this.tokenBeg = tokenBeg;
@ -480,6 +569,10 @@ FilterManyWildcardsHostname.prototype.match = function(url, tokenBeg) {
this.re.test(url.slice(tokenBeg - this.tokenBeg)); this.re.test(url.slice(tokenBeg - this.tokenBeg));
}; };
FilterManyWildcardsHostname.prototype.toString = function() {
return this.s + '$domain=' + this.hostname;
};
/******************************************************************************/ /******************************************************************************/
var makeFilter = function(details, tokenBeg) { var makeFilter = function(details, tokenBeg) {
@ -613,20 +706,10 @@ var trimChar = function(s, c) {
/******************************************************************************/ /******************************************************************************/
var FilterParser = function() { var FilterParser = function() {
this.action = BlockAction;
this.anchor = 0;
this.domains = []; this.domains = [];
this.elemHiding = false;
this.f = '';
this.firstParty = false;
this.fopts = '';
this.hostname = false;
this.hostnames = []; this.hostnames = [];
this.notDomains = [];
this.notHostnames = [];
this.thirdParty = false;
this.types = []; this.types = [];
this.unsupported = false; this.reset();
}; };
/******************************************************************************/ /******************************************************************************/
@ -648,17 +731,16 @@ FilterParser.prototype.toNormalizedType = {
FilterParser.prototype.reset = function() { FilterParser.prototype.reset = function() {
this.action = BlockAction; this.action = BlockAction;
this.anchor = 0; this.anchor = 0;
this.domains = []; this.domains.length = 0;
this.elemHiding = false; this.elemHiding = false;
this.f = ''; this.f = '';
this.firstParty = false; this.firstParty = false;
this.fopts = ''; this.fopts = '';
this.hostname = false; this.hostname = false;
this.hostnames = []; this.hostnames.length = 0;
this.notDomains = []; this.notHostname = false;
this.notHostnames = [];
this.thirdParty = false; this.thirdParty = false;
this.types = []; this.types.length = 0;
this.unsupported = false; this.unsupported = false;
return this; return this;
}; };
@ -710,13 +792,17 @@ FilterParser.prototype.parseOptHostnames = function(raw) {
if ( domain === '' ) { if ( domain === '' ) {
domain = noDomainName; domain = noDomainName;
} }
if ( not ) { // https://github.com/gorhill/uBlock/issues/191
this.notHostnames.push(hostname); // Well it doesn't seem to make a whole lot of sense to have both
this.notDomains.push(domain); // non-negated hostnames mixed with negated hostnames.
} else { if ( this.hostnames.length !== 0 && not !== this.notHostname ) {
this.hostnames.push(hostname); console.error('FilterContainer.parseOptHostnames(): ambiguous filter syntax: "%s"', this.f);
this.domains.push(domain); this.unsupported = true;
return;
} }
this.notHostname = not;
this.hostnames.push(hostname);
this.domains.push(domain);
} }
}; };
@ -811,29 +897,32 @@ FilterParser.prototype.parse = function(s) {
var FilterBucket = function(a, b) { var FilterBucket = function(a, b) {
this.filters = [a, b]; this.filters = [a, b];
this.s = ''; this.f = null;
}; };
/******************************************************************************/
FilterBucket.prototype.add = function(a) { FilterBucket.prototype.add = function(a) {
this.filters.push(a); this.filters.push(a);
}; };
/******************************************************************************/
FilterBucket.prototype.match = function(url, tokenBeg) { FilterBucket.prototype.match = function(url, tokenBeg) {
var filters = this.filters; var filters = this.filters;
var i = filters.length; var i = filters.length;
while ( i-- ) { while ( i-- ) {
if ( filters[i].match(url, tokenBeg) !== false ) { if ( filters[i].match(url, tokenBeg) !== false ) {
this.s = filters[i].s; this.f = filters[i];
return true; return true;
} }
} }
return false; return false;
}; };
FilterBucket.prototype.toString = function() {
if ( this.f !== null ) {
return this.f.toString();
}
return '';
};
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/
@ -996,19 +1085,12 @@ FilterContainer.prototype.addFilter = function(parsed) {
} }
var tokenBeg = matches.index; var tokenBeg = matches.index;
var tokenEnd = parsed.hostname ? reHostnameToken.lastIndex : reGoodToken.lastIndex; var tokenEnd = parsed.hostname ? reHostnameToken.lastIndex : reGoodToken.lastIndex;
var i, n, filter; var filter;
// https://github.com/gorhill/uBlock/issues/191 var i = parsed.hostnames.length;
// Well it doesn't seem to make a whole lot of sense to have both
// non-negated hostnames mixed with negated hostnames.
if ( parsed.hostnames.length && parsed.notHostnames.length ) {
console.error('FilterContainer.addFilter(): ambiguous filter syntax', parsed.f);
return false;
}
if ( parsed.hostnames.length ) { if ( i !== 0 && !parsed.notHostname ) {
n = parsed.hostnames.length; while ( i-- ) {
for ( i = 0; i < n; i++ ) {
filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]); filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]);
if ( !filter ) { if ( !filter ) {
return false; return false;
@ -1026,24 +1108,29 @@ FilterContainer.prototype.addFilter = function(parsed) {
// https://github.com/gorhill/uBlock/issues/191 // https://github.com/gorhill/uBlock/issues/191
// Invert the purpose of the filter for negated hostnames // Invert the purpose of the filter for negated hostnames
if ( parsed.notHostnames.length ) { if ( i !== 0 && parsed.notHostname ) {
filter = makeFilter(parsed, tokenBeg); filter = makeFilter(parsed, tokenBeg);
if ( !filter ) { if ( !filter ) {
return false; return false;
} }
this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd); this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd);
// Reverse purpose of filter // Reverse purpose of filter
parsed.action ^= (BlockAction ^ AllowAction); parsed.action ^= ToggleAction;
n = parsed.notHostnames.length; while ( i-- ) {
for ( i = 0; i < n; i++ ) { filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]);
filter = makeHostnameFilter(parsed, tokenBeg, parsed.notHostnames[i]);
if ( !filter ) { if ( !filter ) {
return false; return false;
} }
// https://github.com/gorhill/uBlock/issues/191#issuecomment-53654024
// If it is a block filter, we need to reverse the order of
// evaluation.
if ( parsed.action === BlockAction ) {
filter.important = true;
}
this.addFilterEntry( this.addFilterEntry(
filter, filter,
parsed, parsed,
SpecificParty | this.toDomainBits(parsed.notDomains[i]), SpecificParty | this.toDomainBits(parsed.domains[i]),
tokenBeg, tokenBeg,
tokenEnd tokenEnd
); );
@ -1123,49 +1210,49 @@ FilterContainer.prototype.matchTokens = function(url) {
if ( bucket0 !== undefined ) { if ( bucket0 !== undefined ) {
f = bucket0[token]; f = bucket0[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket1 !== undefined ) { if ( bucket1 !== undefined ) {
f = bucket1[token]; f = bucket1[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket2 !== undefined ) { if ( bucket2 !== undefined ) {
f = bucket2[token]; f = bucket2[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket3 !== undefined ) { if ( bucket3 !== undefined ) {
f = bucket3[token]; f = bucket3[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket4 !== undefined ) { if ( bucket4 !== undefined ) {
f = bucket4[token]; f = bucket4[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket5 !== undefined ) { if ( bucket5 !== undefined ) {
f = bucket5[token]; f = bucket5[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket6 !== undefined ) { if ( bucket6 !== undefined ) {
f = bucket6[token]; f = bucket6[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
if ( bucket7 !== undefined ) { if ( bucket7 !== undefined ) {
f = bucket7[token]; f = bucket7[token];
if ( f !== undefined && f.match(url, beg) !== false ) { if ( f !== undefined && f.match(url, beg) !== false ) {
return f.s; return f;
} }
} }
} }
@ -1251,24 +1338,31 @@ FilterContainer.prototype.matchStringExactType = function(pageDetails, requestUR
buckets[4] = categories[this.makeCategoryKey(BlockAction | type | party)]; buckets[4] = categories[this.makeCategoryKey(BlockAction | type | party)];
buckets[5] = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)]; buckets[5] = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)];
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)]; buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
var br = this.matchTokens(url); var bf = this.matchTokens(url);
// If there is no block filter, no need to test against allow filters // If there is no block filter, no need to test against allow filters
if ( br === false ) { if ( bf === false ) {
return false; return false;
} }
// The purpose of the `important` property is to reverse the order of
// evaluation. Normally, it is "evaluate block then evaluate allow", with
// the `important` property it is "evaluate allow then evaluate block".
if ( bf.important === true ) {
return bf.toString();
}
// Test against allow filters // Test against allow filters
buckets[3] = categories[this.makeCategoryKey(AllowAnyParty | type)]; buckets[3] = categories[this.makeCategoryKey(AllowAnyParty | type)];
buckets[4] = categories[this.makeCategoryKey(AllowAction | type | party)]; buckets[4] = categories[this.makeCategoryKey(AllowAction | type | party)];
buckets[5] = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)]; buckets[5] = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)];
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)]; buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
var ar = this.matchTokens(url); var af = this.matchTokens(url);
if ( ar !== false ) { if ( af !== false ) {
return '@@' + ar; return '@@' + af.toString();
} }
return br; return bf.toString();
}; };
/******************************************************************************/ /******************************************************************************/
@ -1309,9 +1403,9 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
ThirdParty; ThirdParty;
// Test hostname-based block filters // Test hostname-based block filters
var br = this.matchAnyPartyHostname(requestHostname); var bf = this.matchAnyPartyHostname(requestHostname);
if ( br === false && party === ThirdParty ) { if ( bf === false && party === ThirdParty ) {
br = this.match3rdPartyHostname(requestHostname); bf = this.match3rdPartyHostname(requestHostname);
} }
// This will be used by hostname-based filters // This will be used by hostname-based filters
@ -1323,7 +1417,7 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
var buckets = this.buckets; var buckets = this.buckets;
// Test against block filters // Test against block filters
if ( br === false ) { if ( bf === false ) {
buckets[0] = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)]; buckets[0] = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)];
buckets[1] = categories[this.makeCategoryKey(BlockAnyType | party)]; buckets[1] = categories[this.makeCategoryKey(BlockAnyType | party)];
buckets[2] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)]; buckets[2] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)];
@ -1334,14 +1428,21 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
// Test for synthetic domain as well // Test for synthetic domain as well
buckets[6] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | this.noDomainBits)]; buckets[6] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | this.noDomainBits)];
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)]; buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
br = this.matchTokens(url); bf = this.matchTokens(url);
} }
// If there is no block filter, no need to test against allow filters // If there is no block filter, no need to test against allow filters
if ( br === false ) { if ( bf === false ) {
return false; return false;
} }
// The purpose of the `important` property is to reverse the order of
// evaluation. Normally, it is "evaluate block then evaluate allow", with
// the `important` property it is "evaluate allow then evaluate block".
if ( bf.important === true ) {
return bf.toString();
}
// Test against allow filters // Test against allow filters
buckets[0] = categories[this.makeCategoryKey(AllowAnyTypeAnyParty)]; buckets[0] = categories[this.makeCategoryKey(AllowAnyTypeAnyParty)];
buckets[1] = categories[this.makeCategoryKey(AllowAnyType | party)]; buckets[1] = categories[this.makeCategoryKey(AllowAnyType | party)];
@ -1353,12 +1454,12 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
// Test for synthetic domain as well // Test for synthetic domain as well
buckets[6] = categories[this.makeCategoryKey(AllowAnyTypeOneParty | this.noDomainBits)]; buckets[6] = categories[this.makeCategoryKey(AllowAnyTypeOneParty | this.noDomainBits)];
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)]; buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
var ar = this.matchTokens(url); var af = this.matchTokens(url);
if ( ar !== false ) { if ( af !== false ) {
return '@@' + ar; return '@@' + af.toString();
} }
return br; return bf.toString();
}; };
/******************************************************************************/ /******************************************************************************/