mirror of https://github.com/gorhill/uBlock.git
parent
cfbefd096d
commit
ea49484dd3
|
@ -824,7 +824,7 @@ vAPI.net.registerListeners = function() {
|
||||||
// something else. Test case for "unfriendly" font URLs:
|
// something else. Test case for "unfriendly" font URLs:
|
||||||
// https://www.google.com/fonts
|
// https://www.google.com/fonts
|
||||||
if ( details.type === 'object' ) {
|
if ( details.type === 'object' ) {
|
||||||
if ( headerValue(details.responseHeaders, 'content-type').lastIndexOf('font/', 0) === 0 ) {
|
if ( headerValue(details.responseHeaders, 'content-type').startsWith('font/') ) {
|
||||||
details.type = 'font';
|
details.type = 'font';
|
||||||
var r = onBeforeRequestClient(details);
|
var r = onBeforeRequestClient(details);
|
||||||
if ( typeof r === 'object' && r.cancel === true ) {
|
if ( typeof r === 'object' && r.cancel === true ) {
|
||||||
|
|
|
@ -2361,7 +2361,7 @@ vAPI.net.registerListeners = function() {
|
||||||
var tabId = tabWatcher.tabIdFromTarget(browser);
|
var tabId = tabWatcher.tabIdFromTarget(browser);
|
||||||
|
|
||||||
// Ignore notifications related to our popup
|
// Ignore notifications related to our popup
|
||||||
if ( details.url.lastIndexOf(vAPI.getURL('popup.html'), 0) === 0 ) {
|
if ( details.url.startsWith(vAPI.getURL('popup.html')) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<script src="lib/punycode.js"></script>
|
<script src="lib/punycode.js"></script>
|
||||||
<script src="lib/publicsuffixlist.js"></script>
|
<script src="lib/publicsuffixlist.js"></script>
|
||||||
<script src="lib/yamd5.js"></script>
|
<script src="lib/yamd5.js"></script>
|
||||||
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/vapi-common.js"></script>
|
<script src="js/vapi-common.js"></script>
|
||||||
<script src="js/vapi-background.js"></script>
|
<script src="js/vapi-background.js"></script>
|
||||||
<script src="js/background.js"></script>
|
<script src="js/background.js"></script>
|
||||||
|
|
|
@ -312,7 +312,7 @@ var getTextFileFromURL = function(url, onLoad, onError) {
|
||||||
// appears to be a HTML document: could happen when server serves
|
// appears to be a HTML document: could happen when server serves
|
||||||
// some kind of error page I suppose
|
// some kind of error page I suppose
|
||||||
var text = this.responseText.trim();
|
var text = this.responseText.trim();
|
||||||
if ( text.charAt(0) === '<' && text.slice(-1) === '>' ) {
|
if ( text.startsWith('<') && text.endsWith('>') ) {
|
||||||
return onError.call(this);
|
return onError.call(this);
|
||||||
}
|
}
|
||||||
return onLoad.call(this);
|
return onLoad.call(this);
|
||||||
|
|
|
@ -191,7 +191,7 @@ var FilterHostname = function(s, hostname) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterHostname.prototype.retrieve = function(hostname, out) {
|
FilterHostname.prototype.retrieve = function(hostname, out) {
|
||||||
if ( hostname.slice(-this.hostname.length) === this.hostname ) {
|
if ( hostname.endsWith(this.hostname) ) {
|
||||||
out.push(this.s);
|
out.push(this.s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -219,7 +219,7 @@ var FilterEntity = function(s, entity) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterEntity.prototype.retrieve = function(entity, out) {
|
FilterEntity.prototype.retrieve = function(entity, out) {
|
||||||
if ( entity.slice(-this.entity.length) === this.entity ) {
|
if ( entity.endsWith(this.entity) ) {
|
||||||
out.push(this.s);
|
out.push(this.s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -244,7 +244,6 @@ var FilterParser = function() {
|
||||||
this.hostnames = [];
|
this.hostnames = [];
|
||||||
this.invalid = false;
|
this.invalid = false;
|
||||||
this.cosmetic = true;
|
this.cosmetic = true;
|
||||||
this.reScriptContains = /^script:contains\(.+?\)$/;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -321,7 +320,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
// Cosmetic filters with explicit style properties can apply only:
|
// Cosmetic filters with explicit style properties can apply only:
|
||||||
// - to specific cosmetic filters (those which apply to a specific site)
|
// - to specific cosmetic filters (those which apply to a specific site)
|
||||||
// - to block cosmetic filters (not exception cosmetic filters)
|
// - to block cosmetic filters (not exception cosmetic filters)
|
||||||
if ( this.suffix.slice(-1) === '}' ) {
|
if ( this.suffix.endsWith('}') ) {
|
||||||
// Not supported for now: this code will ensure some backward
|
// Not supported for now: this code will ensure some backward
|
||||||
// compatibility for when cosmetic filters with explicit style
|
// compatibility for when cosmetic filters with explicit style
|
||||||
// properties start to be in use.
|
// properties start to be in use.
|
||||||
|
@ -341,7 +340,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
// Normalize high-medium selectors: `href` is assumed to imply `a` tag. We
|
// Normalize high-medium selectors: `href` is assumed to imply `a` tag. We
|
||||||
// need to do this here in order to correctly avoid duplicates. The test
|
// need to do this here in order to correctly avoid duplicates. The test
|
||||||
// is designed to minimize overhead -- this is a low occurrence filter.
|
// is designed to minimize overhead -- this is a low occurrence filter.
|
||||||
if ( this.suffix.charAt(1) === '[' && this.suffix.slice(2, 9) === 'href^="' ) {
|
if ( this.suffix.startsWith('[href^="', 1) ) {
|
||||||
this.suffix = this.suffix.slice(1);
|
this.suffix = this.suffix.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,9 +356,9 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
|
|
||||||
// Inline script tag filter?
|
// Inline script tag filter?
|
||||||
if (
|
if (
|
||||||
this.suffix.charAt(0) !== 's' ||
|
this.suffix.startsWith('script:contains(') === false ||
|
||||||
this.reScriptContains.test(this.suffix) === false )
|
this.suffix.endsWith(')') === false
|
||||||
{
|
) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,17 +369,17 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var suffix = this.suffix;
|
var suffix = this.suffix.slice(16, -1);
|
||||||
this.suffix = 'script//:';
|
this.suffix = 'script//:';
|
||||||
|
|
||||||
// Plain string-based?
|
// Plain string-based?
|
||||||
if ( suffix.charAt(16) !== '/' || suffix.slice(-2) !== '/)' ) {
|
if ( suffix.startsWith('/') === false || suffix.endsWith('/') === false ) {
|
||||||
this.suffix += suffix.slice(16, -1).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
this.suffix += suffix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regex-based
|
// Regex-based
|
||||||
this.suffix += suffix.slice(17, -2).replace(/\\/g, '\\');
|
this.suffix += suffix.slice(1, -1);
|
||||||
|
|
||||||
// Valid regex?
|
// Valid regex?
|
||||||
if ( isBadRegex(this.suffix) ) {
|
if ( isBadRegex(this.suffix) ) {
|
||||||
|
@ -687,7 +686,7 @@ FilterContainer.prototype.isValidSelector = (function() {
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
if ( s.lastIndexOf('script//:', 0) === 0 ) {
|
if ( s.startsWith('script//:') ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
console.error('uBlock> invalid cosmetic filter:', s);
|
console.error('uBlock> invalid cosmetic filter:', s);
|
||||||
|
@ -730,10 +729,10 @@ FilterContainer.prototype.compile = function(s, out) {
|
||||||
var hostname;
|
var hostname;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
hostname = hostnames[i];
|
hostname = hostnames[i];
|
||||||
if ( hostname.charAt(0) !== '~' ) {
|
if ( hostname.startsWith('~') === false ) {
|
||||||
applyGlobally = false;
|
applyGlobally = false;
|
||||||
}
|
}
|
||||||
if ( hostname.slice(-2) === '.*' ) {
|
if ( hostname.endsWith('.*') ) {
|
||||||
this.compileEntitySelector(hostname, parsed, out);
|
this.compileEntitySelector(hostname, parsed, out);
|
||||||
} else {
|
} else {
|
||||||
this.compileHostnameSelector(hostname, parsed, out);
|
this.compileHostnameSelector(hostname, parsed, out);
|
||||||
|
@ -839,7 +838,7 @@ FilterContainer.prototype.reHighMedium = /^\[href\^="https?:\/\/([^"]{8})[^"]*"\
|
||||||
FilterContainer.prototype.compileHostnameSelector = function(hostname, parsed, out) {
|
FilterContainer.prototype.compileHostnameSelector = function(hostname, parsed, out) {
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/145
|
// https://github.com/chrisaljoudi/uBlock/issues/145
|
||||||
var unhide = parsed.unhide;
|
var unhide = parsed.unhide;
|
||||||
if ( hostname.charAt(0) === '~' ) {
|
if ( hostname.startsWith('~') ) {
|
||||||
hostname = hostname.slice(1);
|
hostname = hostname.slice(1);
|
||||||
unhide ^= 1;
|
unhide ^= 1;
|
||||||
}
|
}
|
||||||
|
@ -915,7 +914,7 @@ 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.
|
// Special filter: script tags. Not a real CSS selector.
|
||||||
if ( fields[3].lastIndexOf('script//:', 0) === 0 ) {
|
if ( fields[3].startsWith('script//:') ) {
|
||||||
this.createScriptTagFilter(fields[2], fields[3].slice(9));
|
this.createScriptTagFilter(fields[2], fields[3].slice(9));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -951,7 +950,7 @@ 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.
|
// Special filter: script tags. Not a real CSS selector.
|
||||||
if ( fields[2].lastIndexOf('script//:', 0) === 0 ) {
|
if ( fields[2].startsWith('script//:') ) {
|
||||||
this.createScriptTagFilter(fields[1], fields[2].slice(9));
|
this.createScriptTagFilter(fields[1], fields[2].slice(9));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1224,16 +1223,17 @@ FilterContainer.prototype.addToSelectorCache = function(details) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.removeFromSelectorCache = function(targetHostname, type) {
|
FilterContainer.prototype.removeFromSelectorCache = function(targetHostname, type) {
|
||||||
|
var targetHostnameLength = targetHostname.length;
|
||||||
for ( var hostname in this.selectorCache ) {
|
for ( var hostname in this.selectorCache ) {
|
||||||
if ( this.selectorCache.hasOwnProperty(hostname) === false ) {
|
if ( this.selectorCache.hasOwnProperty(hostname) === false ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( targetHostname !== '*' ) {
|
if ( targetHostname !== '*' ) {
|
||||||
if ( hostname.slice(0 - targetHostname.length) !== targetHostname ) {
|
if ( hostname.endsWith(targetHostname) === false ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( hostname.length !== targetHostname.length &&
|
if ( hostname.length !== targetHostnameLength &&
|
||||||
hostname.charAt(0 - targetHostname.length - 1) !== '.' ) {
|
hostname.charAt(hostname.length - targetHostnameLength - 1) !== '.' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ var isIPAddress = function(hostname) {
|
||||||
if ( reIPv4VeryCoarse.test(hostname) ) {
|
if ( reIPv4VeryCoarse.test(hostname) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return hostname.charAt(0) === '[';
|
return hostname.startsWith('[');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -325,7 +325,7 @@ var is3rdParty = function(srcHostname, desHostname) {
|
||||||
// etc.
|
// etc.
|
||||||
var srcDomain = domainFromHostname(srcHostname) || srcHostname;
|
var srcDomain = domainFromHostname(srcHostname) || srcHostname;
|
||||||
|
|
||||||
if ( desHostname.slice(0 - srcDomain.length) !== srcDomain ) {
|
if ( desHostname.endsWith(srcDomain) === false ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Do not confuse 'example.com' with 'anotherexample.com'
|
// Do not confuse 'example.com' with 'anotherexample.com'
|
||||||
|
@ -548,7 +548,7 @@ Matrix.prototype.fromString = function(text, append) {
|
||||||
|
|
||||||
// Ignore special rules:
|
// Ignore special rules:
|
||||||
// hostname-based switch rules
|
// hostname-based switch rules
|
||||||
if ( fields[0].slice(-1) === ':' ) {
|
if ( fields[0].endsWith(':') ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ var isIPAddress = function(hostname) {
|
||||||
if ( reIPv4VeryCoarse.test(hostname) ) {
|
if ( reIPv4VeryCoarse.test(hostname) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return hostname.charAt(0) === '[';
|
return hostname.startsWith('[');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -177,7 +177,7 @@ HnSwitches.prototype.toggleBranchZ = function(switchName, targetHostname, newSta
|
||||||
if ( hostname.length <= targetLen ) {
|
if ( hostname.length <= targetLen ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( hostname.slice(-targetLen) !== targetHostname ) {
|
if ( hostname.endsWith(targetHostname) === false ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( hostname.charAt(hostname.length - targetLen - 1) !== '.' ) {
|
if ( hostname.charAt(hostname.length - targetLen - 1) !== '.' ) {
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
var showdomButton = uDom.nodeFromId('showdom');
|
var showdomButton = uDom.nodeFromId('showdom');
|
||||||
|
|
||||||
// Don't bother if the browser is not modern enough.
|
// Don't bother if the browser is not modern enough.
|
||||||
if ( typeof Map === undefined || typeof WeakMap === undefined ) {
|
if ( typeof Map === undefined || Map.polyfill || typeof WeakMap === undefined ) {
|
||||||
showdomButton.classList.add('disabled');
|
showdomButton.classList.add('disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1287,7 +1287,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
if ( pageStore === null ) {
|
if ( pageStore === null ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( pageStore.rawURL.lastIndexOf(loggerURL, 0) === 0 ) {
|
if ( pageStore.rawURL.startsWith(loggerURL) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tabIds[tabId] = pageStore.title;
|
tabIds[tabId] = pageStore.title;
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2015 Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/1067
|
||||||
|
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
||||||
|
// Firefox 17/Chromium 41 supports `startsWith`.
|
||||||
|
|
||||||
|
if ( String.prototype.startsWith instanceof Function === false ) {
|
||||||
|
String.prototype.startsWith = function(needle, pos) {
|
||||||
|
if ( typeof pos !== 'number' ) {
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
return this.lastIndexOf(needle, pos) === pos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/1067
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
||||||
|
// Firefox 17/Chromium 41 supports `endsWith`.
|
||||||
|
|
||||||
|
if ( String.prototype.endsWith instanceof Function === false ) {
|
||||||
|
String.prototype.endsWith = function(needle, pos) {
|
||||||
|
if ( typeof pos !== 'number' ) {
|
||||||
|
pos = this.length;
|
||||||
|
}
|
||||||
|
pos -= needle.length;
|
||||||
|
return this.indexOf(needle, pos) === pos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/1070
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Browser_compatibility
|
||||||
|
// This polyfill is designed to fulfill *only* what uBlock Origin needs -- this
|
||||||
|
// is not an accurate API of the real Set() type.
|
||||||
|
|
||||||
|
if ( typeof self.Set !== 'function' ) {
|
||||||
|
self.Set = function() {
|
||||||
|
this.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Set.polyfill = true;
|
||||||
|
|
||||||
|
self.Set.prototype.clear = function() {
|
||||||
|
this._set = Object.create(null);
|
||||||
|
this.size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Set.prototype.add = function(k) {
|
||||||
|
if ( this._set[k] === undefined ) {
|
||||||
|
this._set[k] = true;
|
||||||
|
this.size += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Set.prototype.delete = function(k) {
|
||||||
|
if ( this._set[k] !== undefined ) {
|
||||||
|
delete this._set[k];
|
||||||
|
this.size -= 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Set.prototype.has = function(k) {
|
||||||
|
return this._set[k] !== undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/1070
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Browser_compatibility
|
||||||
|
// This polyfill is designed to fulfill *only* what uBlock Origin needs -- this
|
||||||
|
// is not an accurate API of the real Map() type.
|
||||||
|
|
||||||
|
if ( typeof self.Map !== 'function' ) {
|
||||||
|
self.Map = function() {
|
||||||
|
this.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Map.polyfill = true;
|
||||||
|
|
||||||
|
self.Map.prototype.clear = function() {
|
||||||
|
this._map = Object.create(null);
|
||||||
|
this.size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Map.prototype.delete = function(k) {
|
||||||
|
if ( this._map[k] !== undefined ) {
|
||||||
|
delete this._map[k];
|
||||||
|
this.size -= 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Map.prototype.get = function(k) {
|
||||||
|
return this._map[k];
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Set.prototype.has = function(k) {
|
||||||
|
return this._map[k] !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.Map.prototype.set = function(k, v) {
|
||||||
|
if ( v !== undefined ) {
|
||||||
|
if ( this._map[k] === undefined ) {
|
||||||
|
this.size += 1;
|
||||||
|
}
|
||||||
|
this._map[k] = v;
|
||||||
|
} else {
|
||||||
|
if ( this._map[k] !== undefined ) {
|
||||||
|
this.size -= 1;
|
||||||
|
}
|
||||||
|
delete this._map[k];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
})();
|
|
@ -227,11 +227,11 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
||||||
var srcs = [];
|
var srcs = [];
|
||||||
var options = matches[3].split(','), option;
|
var options = matches[3].split(','), option;
|
||||||
while ( (option = options.pop()) ) {
|
while ( (option = options.pop()) ) {
|
||||||
if ( option.lastIndexOf('redirect=', 0) === 0 ) {
|
if ( option.startsWith('redirect=') ) {
|
||||||
redirect = option.slice(9);
|
redirect = option.slice(9);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( option.lastIndexOf('domain=', 0) === 0 ) {
|
if ( option.startsWith('domain=') ) {
|
||||||
srcs = option.slice(7).split('|');
|
srcs = option.slice(7).split('|');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need one single type -- not negated.
|
// Need one single type -- not negated.
|
||||||
if ( type === undefined || type.charAt(0) === '~' ) {
|
if ( type === undefined || type.startsWith('~') ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
||||||
if ( src === '' ) {
|
if ( src === '' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( src.charAt(0) === '~' ) {
|
if ( src.startsWith('~') ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Need at least one specific src or des.
|
// Need at least one specific src or des.
|
||||||
|
@ -376,7 +376,7 @@ RedirectEngine.prototype.resourcesFromString = function(text) {
|
||||||
line = text.slice(lineBeg, lineEnd);
|
line = text.slice(lineBeg, lineEnd);
|
||||||
lineBeg = lineEnd + 1;
|
lineBeg = lineEnd + 1;
|
||||||
|
|
||||||
if ( line.charAt(0) === '#' ) {
|
if ( line.startsWith('#') ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ var fromNetFilter = function(details) {
|
||||||
|
|
||||||
var fromCosmeticFilter = function(details) {
|
var fromCosmeticFilter = function(details) {
|
||||||
var filter = details.rawFilter;
|
var filter = details.rawFilter;
|
||||||
var exception = filter.lastIndexOf('#@#', 0) === 0;
|
var exception = filter.startsWith('#@#');
|
||||||
|
|
||||||
filter = exception ? filter.slice(3) : filter.slice(2);
|
filter = exception ? filter.slice(3) : filter.slice(2);
|
||||||
|
|
||||||
|
|
|
@ -168,13 +168,11 @@ var atoi = function(s) {
|
||||||
return cachedParseInt(s, 10);
|
return cachedParseInt(s, 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
var isFirstParty = function(firstPartyDomain, hostname) {
|
var isFirstParty = function(domain, hostname) {
|
||||||
if ( hostname.slice(0 - firstPartyDomain.length) !== firstPartyDomain ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Be sure to not confuse 'example.com' with 'anotherexample.com'
|
// Be sure to not confuse 'example.com' with 'anotherexample.com'
|
||||||
var c = hostname.charAt(hostname.length - firstPartyDomain.length - 1);
|
return hostname.endsWith(domain) &&
|
||||||
return c === '.' || c === '';
|
(hostname.length === domain.length ||
|
||||||
|
hostname.charAt(hostname.length - domain.length - 1) === '.');
|
||||||
};
|
};
|
||||||
|
|
||||||
var isBadRegex = function(s) {
|
var isBadRegex = function(s) {
|
||||||
|
@ -235,26 +233,25 @@ var hostnameTestPicker = function(owner) {
|
||||||
|
|
||||||
// Only one hostname
|
// Only one hostname
|
||||||
if ( domainOpt.indexOf('|') === -1 ) {
|
if ( domainOpt.indexOf('|') === -1 ) {
|
||||||
return domainOpt.charAt(0) !== '~' ? hostnameHitTest : hostnameMissTest;
|
return domainOpt.startsWith('~') ? hostnameMissTest : hostnameHitTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiple hostnames: use a dictionary.
|
// Multiple hostnames: use a dictionary.
|
||||||
var dict = owner._hostnameDict = Object.create(null);
|
|
||||||
var hostnames = domainOpt.split('|');
|
var hostnames = domainOpt.split('|');
|
||||||
var i, hostname;
|
var i, hostname, dict;
|
||||||
|
|
||||||
// First find out whether we have a homogeneous dictionary
|
// First find out whether we have a homogeneous dictionary
|
||||||
var hit = false, miss = false;
|
var hit = false, miss = false;
|
||||||
i = hostnames.length;
|
i = hostnames.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
if ( hostnames[i].charAt(0) !== '~' ) {
|
if ( hostnames[i].startsWith('~') ) {
|
||||||
hit = true;
|
miss = true;
|
||||||
if ( miss ) {
|
if ( hit ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
miss = true;
|
hit = true;
|
||||||
if ( hit ) {
|
if ( miss ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,40 +261,44 @@ var hostnameTestPicker = function(owner) {
|
||||||
// Spotted one occurrence in EasyList Lite (cjxlist.txt):
|
// Spotted one occurrence in EasyList Lite (cjxlist.txt):
|
||||||
// domain=photobucket.com|~secure.photobucket.com
|
// domain=photobucket.com|~secure.photobucket.com
|
||||||
if ( hit && miss ) {
|
if ( hit && miss ) {
|
||||||
|
dict = owner._hostnameDict = new Map();
|
||||||
i = hostnames.length;
|
i = hostnames.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
hostname = hostnames[i];
|
hostname = hostnames[i];
|
||||||
if ( hostname.charAt(0) !== '~' ) {
|
if ( hostname.startsWith('~') ) {
|
||||||
dict[hostname] = true;
|
dict.set(hostname.slice(1), false);
|
||||||
} else {
|
} else {
|
||||||
dict[hostname.slice(1)] = false;
|
dict.set(hostname, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hostnameMixedSetTest;
|
return hostnameMixedSetTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Homogeneous dictionary.
|
// Homogeneous dictionary.
|
||||||
|
dict = owner._hostnameDict = new Set();
|
||||||
i = hostnames.length;
|
i = hostnames.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
hostname = hostnames[i];
|
hostname = hostnames[i];
|
||||||
if ( hostname.charAt(0) !== '~' ) {
|
dict.add(hostname.startsWith('~') ? hostname.slice(1) : hostname);
|
||||||
dict[hostname] = true;
|
|
||||||
} else {
|
|
||||||
dict[hostname.slice(1)] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hit ? hostnameHitSetTest : hostnameMissSetTest;
|
return hit ? hostnameHitSetTest : hostnameMissSetTest;
|
||||||
};
|
};
|
||||||
|
|
||||||
var hostnameHitTest = function(owner) {
|
var hostnameHitTest = function(owner) {
|
||||||
var hostname = owner.domainOpt;
|
var current = pageHostnameRegister;
|
||||||
return pageHostnameRegister.slice(0 - hostname.length) === hostname;
|
var target = owner.domainOpt;
|
||||||
|
return current.endsWith(target) &&
|
||||||
|
(current.length === target.length ||
|
||||||
|
current.charAt(current.length - target.length - 1) === '.');
|
||||||
};
|
};
|
||||||
|
|
||||||
var hostnameMissTest = function(owner) {
|
var hostnameMissTest = function(owner) {
|
||||||
var hostname = owner.domainOpt;
|
var current = pageHostnameRegister;
|
||||||
return pageHostnameRegister.slice(1 - hostname.length) !== hostname.slice(1);
|
var target = owner.domainOpt;
|
||||||
|
return current.endsWith(target) === false ||
|
||||||
|
(current.length !== target.length &&
|
||||||
|
current.charAt(current.length - target.length - 1) !== '.');
|
||||||
};
|
};
|
||||||
|
|
||||||
var hostnameHitSetTest = function(owner) {
|
var hostnameHitSetTest = function(owner) {
|
||||||
|
@ -305,7 +306,7 @@ var hostnameHitSetTest = function(owner) {
|
||||||
var needle = pageHostnameRegister;
|
var needle = pageHostnameRegister;
|
||||||
var pos;
|
var pos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( dict[needle] ) {
|
if ( dict.has(needle) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
pos = needle.indexOf('.');
|
pos = needle.indexOf('.');
|
||||||
|
@ -322,7 +323,7 @@ var hostnameMissSetTest = function(owner) {
|
||||||
var needle = pageHostnameRegister;
|
var needle = pageHostnameRegister;
|
||||||
var pos;
|
var pos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( dict[needle] ) {
|
if ( dict.has(needle) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pos = needle.indexOf('.');
|
pos = needle.indexOf('.');
|
||||||
|
@ -341,11 +342,11 @@ var hostnameMixedSetTest = function(owner) {
|
||||||
var hit = false;
|
var hit = false;
|
||||||
var v, pos;
|
var v, pos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
v = dict[needle] || undefined;
|
v = dict.get(needle);
|
||||||
if ( v === false ) {
|
if ( v === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( v /* === true */ ) {
|
if ( v === true ) {
|
||||||
hit = true;
|
hit = true;
|
||||||
}
|
}
|
||||||
pos = needle.indexOf('.');
|
pos = needle.indexOf('.');
|
||||||
|
@ -393,7 +394,7 @@ var FilterPlain = function(s, tokenBeg) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlain.prototype.match = function(url, tokenBeg) {
|
FilterPlain.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
return url.startsWith(this.s, tokenBeg - this.tokenBeg);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlain.fid =
|
FilterPlain.fid =
|
||||||
|
@ -424,8 +425,8 @@ var FilterPlainHostname = function(s, tokenBeg, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
||||||
return this.hostnameTest(this) &&
|
return url.startsWith(this.s, tokenBeg - this.tokenBeg) &&
|
||||||
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
this.hostnameTest(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHostname.fid =
|
FilterPlainHostname.fid =
|
||||||
|
@ -453,7 +454,7 @@ var FilterPlainPrefix0 = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg, this.s.length) === this.s;
|
return url.startsWith(this.s, tokenBeg);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix0.fid =
|
FilterPlainPrefix0.fid =
|
||||||
|
@ -482,8 +483,8 @@ var FilterPlainPrefix0Hostname = function(s, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
return this.hostnameTest(this) &&
|
return url.startsWith(this.s, tokenBeg) &&
|
||||||
url.substr(tokenBeg, this.s.length) === this.s;
|
this.hostnameTest(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix0Hostname.fid =
|
FilterPlainPrefix0Hostname.fid =
|
||||||
|
@ -511,7 +512,7 @@ var FilterPlainPrefix1 = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix1.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix1.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg - 1, this.s.length) === this.s;
|
return url.startsWith(this.s, tokenBeg - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix1.fid =
|
FilterPlainPrefix1.fid =
|
||||||
|
@ -540,8 +541,8 @@ var FilterPlainPrefix1Hostname = function(s, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
return this.hostnameTest(this) &&
|
return url.startsWith(this.s, tokenBeg - 1) &&
|
||||||
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
this.hostnameTest(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix1Hostname.fid =
|
FilterPlainPrefix1Hostname.fid =
|
||||||
|
@ -569,7 +570,7 @@ var FilterPlainLeftAnchored = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainLeftAnchored.prototype.match = function(url) {
|
FilterPlainLeftAnchored.prototype.match = function(url) {
|
||||||
return url.slice(0, this.s.length) === this.s;
|
return url.startsWith(this.s);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainLeftAnchored.fid =
|
FilterPlainLeftAnchored.fid =
|
||||||
|
@ -598,8 +599,8 @@ var FilterPlainLeftAnchoredHostname = function(s, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
||||||
return this.hostnameTest(this) &&
|
return url.startsWith(this.s) &&
|
||||||
url.slice(0, this.s.length) === this.s;
|
this.hostnameTest(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainLeftAnchoredHostname.fid =
|
FilterPlainLeftAnchoredHostname.fid =
|
||||||
|
@ -627,7 +628,7 @@ var FilterPlainRightAnchored = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainRightAnchored.prototype.match = function(url) {
|
FilterPlainRightAnchored.prototype.match = function(url) {
|
||||||
return url.slice(-this.s.length) === this.s;
|
return url.endsWith(this.s);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainRightAnchored.fid =
|
FilterPlainRightAnchored.fid =
|
||||||
|
@ -656,8 +657,8 @@ var FilterPlainRightAnchoredHostname = function(s, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||||
return this.hostnameTest(this) &&
|
return url.endsWith(this.s) &&
|
||||||
url.slice(-this.s.length) === this.s;
|
this.hostnameTest(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainRightAnchoredHostname.fid =
|
FilterPlainRightAnchoredHostname.fid =
|
||||||
|
@ -688,7 +689,7 @@ var FilterPlainHnAnchored = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHnAnchored.prototype.match = function(url, tokenBeg) {
|
FilterPlainHnAnchored.prototype.match = function(url, tokenBeg) {
|
||||||
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
if ( url.startsWith(this.s, tokenBeg) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Valid only if hostname-valid characters to the left of token
|
// Valid only if hostname-valid characters to the left of token
|
||||||
|
@ -715,6 +716,7 @@ FilterPlainHnAnchored.fromSelfie = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://www.youtube.com/watch?v=71YS6xDB-E4
|
// https://www.youtube.com/watch?v=71YS6xDB-E4
|
||||||
|
// https://www.youtube.com/watch?v=qBPML7ton0E
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -727,10 +729,10 @@ var FilterPlainHnAnchoredHostname = function(s, domainOpt) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
||||||
if ( this.hostnameTest(this) === false ) {
|
if (
|
||||||
return false;
|
url.startsWith(this.s, tokenBeg) === false ||
|
||||||
}
|
this.hostnameTest(this) === false
|
||||||
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Valid only if hostname-valid characters to the left of token
|
// Valid only if hostname-valid characters to the left of token
|
||||||
|
@ -805,10 +807,8 @@ FilterGenericHostname.prototype = Object.create(FilterGeneric.prototype);
|
||||||
FilterGenericHostname.prototype.constructor = FilterGenericHostname;
|
FilterGenericHostname.prototype.constructor = FilterGenericHostname;
|
||||||
|
|
||||||
FilterGenericHostname.prototype.match = function(url) {
|
FilterGenericHostname.prototype.match = function(url) {
|
||||||
if ( this.hostnameTest(this) === false ) {
|
return this.hostnameTest(this) &&
|
||||||
return false;
|
FilterGeneric.prototype.match.call(this, url);
|
||||||
}
|
|
||||||
return FilterGeneric.prototype.match.call(this, url);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterGenericHostname.fid =
|
FilterGenericHostname.fid =
|
||||||
|
@ -884,10 +884,8 @@ FilterGenericHnAnchoredHostname.prototype = Object.create(FilterGenericHnAnchore
|
||||||
FilterGenericHnAnchoredHostname.prototype.constructor = FilterGenericHnAnchoredHostname;
|
FilterGenericHnAnchoredHostname.prototype.constructor = FilterGenericHnAnchoredHostname;
|
||||||
|
|
||||||
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
||||||
if ( this.hostnameTest(this) === false ) {
|
return this.hostnameTest(this) &&
|
||||||
return false;
|
FilterGenericHnAnchored.prototype.match.call(this, url);
|
||||||
}
|
|
||||||
return FilterGenericHnAnchored.prototype.match.call(this, url);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterGenericHnAnchoredHostname.fid =
|
FilterGenericHnAnchoredHostname.fid =
|
||||||
|
@ -1004,7 +1002,7 @@ FilterHostnameDict.prototype.cutoff = 250;
|
||||||
|
|
||||||
FilterHostnameDict.prototype.meltBucket = function(len, bucket) {
|
FilterHostnameDict.prototype.meltBucket = function(len, bucket) {
|
||||||
var map = {};
|
var map = {};
|
||||||
if ( bucket.charAt(0) === ' ' ) {
|
if ( bucket.startsWith(' ') ) {
|
||||||
bucket.trim().split(' ').map(function(k) {
|
bucket.trim().split(' ').map(function(k) {
|
||||||
map[k] = true;
|
map[k] = true;
|
||||||
});
|
});
|
||||||
|
@ -1105,7 +1103,7 @@ FilterHostnameDict.prototype.matchesExactly = function(hn) {
|
||||||
if ( typeof bucket === 'object' ) {
|
if ( typeof bucket === 'object' ) {
|
||||||
bucket = this.dict[key] = this.freezeBucket(bucket);
|
bucket = this.dict[key] = this.freezeBucket(bucket);
|
||||||
}
|
}
|
||||||
if ( bucket.charAt(0) === ' ' ) {
|
if ( bucket.startsWith(' ') ) {
|
||||||
return bucket.indexOf(' ' + hn + ' ') !== -1;
|
return bucket.indexOf(' ' + hn + ' ') !== -1;
|
||||||
}
|
}
|
||||||
// binary search
|
// binary search
|
||||||
|
@ -1379,7 +1377,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
||||||
var opt, not;
|
var opt, not;
|
||||||
for ( var i = 0; i < opts.length; i++ ) {
|
for ( var i = 0; i < opts.length; i++ ) {
|
||||||
opt = opts[i];
|
opt = opts[i];
|
||||||
not = opt.charAt(0) === '~';
|
not = opt.startsWith('~');
|
||||||
if ( not ) {
|
if ( not ) {
|
||||||
opt = opt.slice(1);
|
opt = opt.slice(1);
|
||||||
}
|
}
|
||||||
|
@ -1411,7 +1409,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
||||||
this.parseOptType(opt, not);
|
this.parseOptType(opt, not);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( opt.lastIndexOf('domain=', 0) === 0 ) {
|
if ( opt.startsWith('domain=') ) {
|
||||||
this.domainOpt = opt.slice(7);
|
this.domainOpt = opt.slice(7);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1421,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
||||||
this.parseOptParty(true, not);
|
this.parseOptParty(true, not);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( opt.lastIndexOf('redirect=', 0) === 0 ) {
|
if ( opt.startsWith('redirect=') ) {
|
||||||
if ( this.action === BlockAction ) {
|
if ( this.action === BlockAction ) {
|
||||||
this.redirect = true;
|
this.redirect = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1466,7 +1464,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
|
|
||||||
// block or allow filter?
|
// block or allow filter?
|
||||||
// Important: this must be executed before parsing options
|
// Important: this must be executed before parsing options
|
||||||
if ( s.lastIndexOf('@@', 0) === 0 ) {
|
if ( s.startsWith('@@') ) {
|
||||||
this.action = AllowAction;
|
this.action = AllowAction;
|
||||||
s = s.slice(2);
|
s = s.slice(2);
|
||||||
}
|
}
|
||||||
|
@ -1475,7 +1473,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
// https://github.com/gorhill/uBlock/issues/842
|
// https://github.com/gorhill/uBlock/issues/842
|
||||||
// - ensure sure we are not dealing with a regex-based filter.
|
// - ensure sure we are not dealing with a regex-based filter.
|
||||||
// - lookup the last occurrence of `$`.
|
// - lookup the last occurrence of `$`.
|
||||||
if ( s.charAt(0) !== '/' || s.slice(-1) !== '/' ) {
|
if ( s.startsWith('/') === false || s.endsWith('/') === false ) {
|
||||||
pos = s.lastIndexOf('$');
|
pos = s.lastIndexOf('$');
|
||||||
if ( pos !== -1 ) {
|
if ( pos !== -1 ) {
|
||||||
// https://github.com/gorhill/uBlock/issues/952
|
// https://github.com/gorhill/uBlock/issues/952
|
||||||
|
@ -1490,7 +1488,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// regex?
|
// regex?
|
||||||
if ( s.charAt(0) === '/' && s.slice(-1) === '/' && s.length > 2 ) {
|
if ( s.startsWith('/') && s.endsWith('/') && s.length > 2 ) {
|
||||||
this.isRegex = true;
|
this.isRegex = true;
|
||||||
this.f = s.slice(1, -1);
|
this.f = s.slice(1, -1);
|
||||||
if ( isBadRegex(this.f) ) {
|
if ( isBadRegex(this.f) ) {
|
||||||
|
@ -1505,7 +1503,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// hostname-anchored
|
// hostname-anchored
|
||||||
if ( s.lastIndexOf('||', 0) === 0 ) {
|
if ( s.startsWith('||') ) {
|
||||||
this.hostnameAnchored = true;
|
this.hostnameAnchored = true;
|
||||||
s = s.slice(2);
|
s = s.slice(2);
|
||||||
|
|
||||||
|
@ -1519,7 +1517,7 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/1096
|
// https://github.com/chrisaljoudi/uBlock/issues/1096
|
||||||
if ( s.charAt(0) === '^' ) {
|
if ( s.startsWith('^') ) {
|
||||||
this.unsupported = true;
|
this.unsupported = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1533,13 +1531,13 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// left-anchored
|
// left-anchored
|
||||||
if ( s.charAt(0) === '|' ) {
|
if ( s.startsWith('|') ) {
|
||||||
this.anchor = -1;
|
this.anchor = -1;
|
||||||
s = s.slice(1);
|
s = s.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// right-anchored
|
// right-anchored
|
||||||
if ( s.slice(-1) === '|' ) {
|
if ( s.endsWith('|') ) {
|
||||||
this.anchor = 1;
|
this.anchor = 1;
|
||||||
s = s.slice(0, -1);
|
s = s.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
@ -1547,11 +1545,11 @@ FilterParser.prototype.parse = function(raw) {
|
||||||
// normalize placeholders
|
// normalize placeholders
|
||||||
if ( this.reHasWildcard.test(s) ) {
|
if ( this.reHasWildcard.test(s) ) {
|
||||||
// remove pointless leading *
|
// remove pointless leading *
|
||||||
if ( s.charAt(0) === '*' ) {
|
if ( s.startsWith('*') ) {
|
||||||
s = s.replace(/^\*+([^%0-9a-z])/, '$1');
|
s = s.replace(/^\*+([^%0-9a-z])/, '$1');
|
||||||
}
|
}
|
||||||
// remove pointless trailing *
|
// remove pointless trailing *
|
||||||
if ( s.slice(-1) === '*' ) {
|
if ( s.endsWith('*') ) {
|
||||||
s = s.replace(/([^%0-9a-z])\*+$/, '$1');
|
s = s.replace(/([^%0-9a-z])\*+$/, '$1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@
|
||||||
// https://github.com/gorhill/uBlock/issues/277
|
// https://github.com/gorhill/uBlock/issues/277
|
||||||
// uBlock's filter lists are always enabled by default, so we
|
// uBlock's filter lists are always enabled by default, so we
|
||||||
// have to include in backup only those which are turned off.
|
// have to include in backup only those which are turned off.
|
||||||
if ( path.lastIndexOf('assets/ublock/', 0) === 0 ) {
|
if ( path.startsWith('assets/ublock/') ) {
|
||||||
if ( entry.off !== true ) {
|
if ( entry.off !== true ) {
|
||||||
delete result[path];
|
delete result[path];
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,7 +453,7 @@ vAPI.tabs.onNavigation = function(details) {
|
||||||
// TODO: Eventually, we will have to use an API to check whether a scheme
|
// TODO: Eventually, we will have to use an API to check whether a scheme
|
||||||
// is supported as I suspect we are going to start to see `ws`, `wss`
|
// is supported as I suspect we are going to start to see `ws`, `wss`
|
||||||
// as well soon.
|
// as well soon.
|
||||||
if ( pageStore && tabContext.rawURL.lastIndexOf('http', 0) === 0 ) {
|
if ( pageStore && tabContext.rawURL.startsWith('http') ) {
|
||||||
pageStore.hostnameToCountMap[tabContext.rootHostname] = 0;
|
pageStore.hostnameToCountMap[tabContext.rootHostname] = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -618,7 +618,7 @@ vAPI.tabs.onPopupUpdated = (function() {
|
||||||
|
|
||||||
// If the page URL is that of our "blocked page" URL, extract the URL of
|
// If the page URL is that of our "blocked page" URL, extract the URL of
|
||||||
// the page which was blocked.
|
// the page which was blocked.
|
||||||
if ( targetURL.lastIndexOf(vAPI.getURL('document-blocked.html'), 0) === 0 ) {
|
if ( targetURL.startsWith(vAPI.getURL('document-blocked.html')) ) {
|
||||||
var matches = /details=([^&]+)/.exec(targetURL);
|
var matches = /details=([^&]+)/.exec(targetURL);
|
||||||
if ( matches !== null ) {
|
if ( matches !== null ) {
|
||||||
targetURL = JSON.parse(atob(matches[1])).url;
|
targetURL = JSON.parse(atob(matches[1])).url;
|
||||||
|
|
|
@ -47,7 +47,9 @@ var isHandcraftedWhitelistDirective = function(directive) {
|
||||||
var matchWhitelistDirective = function(url, hostname, directive) {
|
var matchWhitelistDirective = function(url, hostname, directive) {
|
||||||
// Directive is a plain hostname
|
// Directive is a plain hostname
|
||||||
if ( directive.indexOf('/') === -1 ) {
|
if ( directive.indexOf('/') === -1 ) {
|
||||||
return hostname.slice(-directive.length) === directive;
|
return hostname.endsWith(directive) &&
|
||||||
|
(hostname.length === directive.length ||
|
||||||
|
hostname.charAt(hostname.length - directive.length - 1) === '.');
|
||||||
}
|
}
|
||||||
// Match URL exactly
|
// Match URL exactly
|
||||||
if ( directive.indexOf('*') === -1 ) {
|
if ( directive.indexOf('*') === -1 ) {
|
||||||
|
@ -187,7 +189,7 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't throw out commented out lines: user might want to fix them
|
// Don't throw out commented out lines: user might want to fix them
|
||||||
if ( line.charAt(0) === '#' ) {
|
if ( line.startsWith('#') ) {
|
||||||
key = '#';
|
key = '#';
|
||||||
directive = line;
|
directive = line;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ URI.set = function(uri) {
|
||||||
}
|
}
|
||||||
this.hostname = matches[1] !== undefined ? matches[1] : '';
|
this.hostname = matches[1] !== undefined ? matches[1] : '';
|
||||||
// http://en.wikipedia.org/wiki/FQDN
|
// http://en.wikipedia.org/wiki/FQDN
|
||||||
if ( this.hostname.slice(-1) === '.' ) {
|
if ( this.hostname.endsWith('.') ) {
|
||||||
this.hostname = this.hostname.slice(0, -1);
|
this.hostname = this.hostname.slice(0, -1);
|
||||||
}
|
}
|
||||||
this.port = matches[2] !== undefined ? matches[2].slice(1) : '';
|
this.port = matches[2] !== undefined ? matches[2].slice(1) : '';
|
||||||
|
@ -271,7 +271,7 @@ URI.hostnameFromURI = function(uri) {
|
||||||
}
|
}
|
||||||
// http://en.wikipedia.org/wiki/FQDN
|
// http://en.wikipedia.org/wiki/FQDN
|
||||||
var hostname = matches[1];
|
var hostname = matches[1];
|
||||||
if ( hostname.slice(-1) === '.' ) {
|
if ( hostname.endsWith('.') ) {
|
||||||
hostname = hostname.slice(0, -1);
|
hostname = hostname.slice(0, -1);
|
||||||
}
|
}
|
||||||
return hostname.toLowerCase();
|
return hostname.toLowerCase();
|
||||||
|
|
|
@ -92,7 +92,7 @@ var indexOfMatch = function(urls, url) {
|
||||||
if ( entry.url.length > urlLen ) {
|
if ( entry.url.length > urlLen ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( url.lastIndexOf(entry.url, 0) === 0 ) {
|
if ( url.startsWith(entry.url) ) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue