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:
|
||||
// https://www.google.com/fonts
|
||||
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';
|
||||
var r = onBeforeRequestClient(details);
|
||||
if ( typeof r === 'object' && r.cancel === true ) {
|
||||
|
|
|
@ -2361,7 +2361,7 @@ vAPI.net.registerListeners = function() {
|
|||
var tabId = tabWatcher.tabIdFromTarget(browser);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<script src="lib/punycode.js"></script>
|
||||
<script src="lib/publicsuffixlist.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-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
|
||||
// some kind of error page I suppose
|
||||
var text = this.responseText.trim();
|
||||
if ( text.charAt(0) === '<' && text.slice(-1) === '>' ) {
|
||||
if ( text.startsWith('<') && text.endsWith('>') ) {
|
||||
return onError.call(this);
|
||||
}
|
||||
return onLoad.call(this);
|
||||
|
|
|
@ -191,7 +191,7 @@ var FilterHostname = function(s, hostname) {
|
|||
};
|
||||
|
||||
FilterHostname.prototype.retrieve = function(hostname, out) {
|
||||
if ( hostname.slice(-this.hostname.length) === this.hostname ) {
|
||||
if ( hostname.endsWith(this.hostname) ) {
|
||||
out.push(this.s);
|
||||
}
|
||||
};
|
||||
|
@ -219,7 +219,7 @@ var FilterEntity = function(s, entity) {
|
|||
};
|
||||
|
||||
FilterEntity.prototype.retrieve = function(entity, out) {
|
||||
if ( entity.slice(-this.entity.length) === this.entity ) {
|
||||
if ( entity.endsWith(this.entity) ) {
|
||||
out.push(this.s);
|
||||
}
|
||||
};
|
||||
|
@ -244,7 +244,6 @@ var FilterParser = function() {
|
|||
this.hostnames = [];
|
||||
this.invalid = false;
|
||||
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:
|
||||
// - to specific cosmetic filters (those which apply to a specific site)
|
||||
// - 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
|
||||
// compatibility for when cosmetic filters with explicit style
|
||||
// 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
|
||||
// need to do this here in order to correctly avoid duplicates. The test
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -357,9 +356,9 @@ FilterParser.prototype.parse = function(raw) {
|
|||
|
||||
// Inline script tag filter?
|
||||
if (
|
||||
this.suffix.charAt(0) !== 's' ||
|
||||
this.reScriptContains.test(this.suffix) === false )
|
||||
{
|
||||
this.suffix.startsWith('script:contains(') === false ||
|
||||
this.suffix.endsWith(')') === false
|
||||
) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -370,17 +369,17 @@ FilterParser.prototype.parse = function(raw) {
|
|||
return this;
|
||||
}
|
||||
|
||||
var suffix = this.suffix;
|
||||
var suffix = this.suffix.slice(16, -1);
|
||||
this.suffix = 'script//:';
|
||||
|
||||
// Plain string-based?
|
||||
if ( suffix.charAt(16) !== '/' || suffix.slice(-2) !== '/)' ) {
|
||||
this.suffix += suffix.slice(16, -1).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
if ( suffix.startsWith('/') === false || suffix.endsWith('/') === false ) {
|
||||
this.suffix += suffix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
return this;
|
||||
}
|
||||
|
||||
// Regex-based
|
||||
this.suffix += suffix.slice(17, -2).replace(/\\/g, '\\');
|
||||
this.suffix += suffix.slice(1, -1);
|
||||
|
||||
// Valid regex?
|
||||
if ( isBadRegex(this.suffix) ) {
|
||||
|
@ -687,7 +686,7 @@ FilterContainer.prototype.isValidSelector = (function() {
|
|||
return true;
|
||||
} catch (e) {
|
||||
}
|
||||
if ( s.lastIndexOf('script//:', 0) === 0 ) {
|
||||
if ( s.startsWith('script//:') ) {
|
||||
return true;
|
||||
}
|
||||
console.error('uBlock> invalid cosmetic filter:', s);
|
||||
|
@ -730,10 +729,10 @@ FilterContainer.prototype.compile = function(s, out) {
|
|||
var hostname;
|
||||
while ( i-- ) {
|
||||
hostname = hostnames[i];
|
||||
if ( hostname.charAt(0) !== '~' ) {
|
||||
if ( hostname.startsWith('~') === false ) {
|
||||
applyGlobally = false;
|
||||
}
|
||||
if ( hostname.slice(-2) === '.*' ) {
|
||||
if ( hostname.endsWith('.*') ) {
|
||||
this.compileEntitySelector(hostname, parsed, out);
|
||||
} else {
|
||||
this.compileHostnameSelector(hostname, parsed, out);
|
||||
|
@ -839,7 +838,7 @@ FilterContainer.prototype.reHighMedium = /^\[href\^="https?:\/\/([^"]{8})[^"]*"\
|
|||
FilterContainer.prototype.compileHostnameSelector = function(hostname, parsed, out) {
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/145
|
||||
var unhide = parsed.unhide;
|
||||
if ( hostname.charAt(0) === '~' ) {
|
||||
if ( hostname.startsWith('~') ) {
|
||||
hostname = hostname.slice(1);
|
||||
unhide ^= 1;
|
||||
}
|
||||
|
@ -915,7 +914,7 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||
// h ir twitter.com .promoted-tweet
|
||||
if ( fields[0] === 'h' ) {
|
||||
// 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));
|
||||
continue;
|
||||
}
|
||||
|
@ -951,7 +950,7 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||
// entity selector
|
||||
if ( fields[0] === 'e' ) {
|
||||
// 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));
|
||||
continue;
|
||||
}
|
||||
|
@ -1224,16 +1223,17 @@ FilterContainer.prototype.addToSelectorCache = function(details) {
|
|||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.removeFromSelectorCache = function(targetHostname, type) {
|
||||
var targetHostnameLength = targetHostname.length;
|
||||
for ( var hostname in this.selectorCache ) {
|
||||
if ( this.selectorCache.hasOwnProperty(hostname) === false ) {
|
||||
continue;
|
||||
}
|
||||
if ( targetHostname !== '*' ) {
|
||||
if ( hostname.slice(0 - targetHostname.length) !== targetHostname ) {
|
||||
if ( hostname.endsWith(targetHostname) === false ) {
|
||||
continue;
|
||||
}
|
||||
if ( hostname.length !== targetHostname.length &&
|
||||
hostname.charAt(0 - targetHostname.length - 1) !== '.' ) {
|
||||
if ( hostname.length !== targetHostnameLength &&
|
||||
hostname.charAt(hostname.length - targetHostnameLength - 1) !== '.' ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ var isIPAddress = function(hostname) {
|
|||
if ( reIPv4VeryCoarse.test(hostname) ) {
|
||||
return true;
|
||||
}
|
||||
return hostname.charAt(0) === '[';
|
||||
return hostname.startsWith('[');
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -325,7 +325,7 @@ var is3rdParty = function(srcHostname, desHostname) {
|
|||
// etc.
|
||||
var srcDomain = domainFromHostname(srcHostname) || srcHostname;
|
||||
|
||||
if ( desHostname.slice(0 - srcDomain.length) !== srcDomain ) {
|
||||
if ( desHostname.endsWith(srcDomain) === false ) {
|
||||
return true;
|
||||
}
|
||||
// Do not confuse 'example.com' with 'anotherexample.com'
|
||||
|
@ -548,7 +548,7 @@ Matrix.prototype.fromString = function(text, append) {
|
|||
|
||||
// Ignore special rules:
|
||||
// hostname-based switch rules
|
||||
if ( fields[0].slice(-1) === ':' ) {
|
||||
if ( fields[0].endsWith(':') ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ var isIPAddress = function(hostname) {
|
|||
if ( reIPv4VeryCoarse.test(hostname) ) {
|
||||
return true;
|
||||
}
|
||||
return hostname.charAt(0) === '[';
|
||||
return hostname.startsWith('[');
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -177,7 +177,7 @@ HnSwitches.prototype.toggleBranchZ = function(switchName, targetHostname, newSta
|
|||
if ( hostname.length <= targetLen ) {
|
||||
continue;
|
||||
}
|
||||
if ( hostname.slice(-targetLen) !== targetHostname ) {
|
||||
if ( hostname.endsWith(targetHostname) === false ) {
|
||||
continue;
|
||||
}
|
||||
if ( hostname.charAt(hostname.length - targetLen - 1) !== '.' ) {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
var showdomButton = uDom.nodeFromId('showdom');
|
||||
|
||||
// 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');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1287,7 +1287,7 @@ var onMessage = function(request, sender, callback) {
|
|||
if ( pageStore === null ) {
|
||||
continue;
|
||||
}
|
||||
if ( pageStore.rawURL.lastIndexOf(loggerURL, 0) === 0 ) {
|
||||
if ( pageStore.rawURL.startsWith(loggerURL) ) {
|
||||
continue;
|
||||
}
|
||||
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 options = matches[3].split(','), option;
|
||||
while ( (option = options.pop()) ) {
|
||||
if ( option.lastIndexOf('redirect=', 0) === 0 ) {
|
||||
if ( option.startsWith('redirect=') ) {
|
||||
redirect = option.slice(9);
|
||||
continue;
|
||||
}
|
||||
if ( option.lastIndexOf('domain=', 0) === 0 ) {
|
||||
if ( option.startsWith('domain=') ) {
|
||||
srcs = option.slice(7).split('|');
|
||||
continue;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
|||
}
|
||||
|
||||
// Need one single type -- not negated.
|
||||
if ( type === undefined || type.charAt(0) === '~' ) {
|
||||
if ( type === undefined || type.startsWith('~') ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
|||
if ( src === '' ) {
|
||||
continue;
|
||||
}
|
||||
if ( src.charAt(0) === '~' ) {
|
||||
if ( src.startsWith('~') ) {
|
||||
continue;
|
||||
}
|
||||
// Need at least one specific src or des.
|
||||
|
@ -376,7 +376,7 @@ RedirectEngine.prototype.resourcesFromString = function(text) {
|
|||
line = text.slice(lineBeg, lineEnd);
|
||||
lineBeg = lineEnd + 1;
|
||||
|
||||
if ( line.charAt(0) === '#' ) {
|
||||
if ( line.startsWith('#') ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ var fromNetFilter = function(details) {
|
|||
|
||||
var fromCosmeticFilter = function(details) {
|
||||
var filter = details.rawFilter;
|
||||
var exception = filter.lastIndexOf('#@#', 0) === 0;
|
||||
var exception = filter.startsWith('#@#');
|
||||
|
||||
filter = exception ? filter.slice(3) : filter.slice(2);
|
||||
|
||||
|
|
|
@ -168,13 +168,11 @@ var atoi = function(s) {
|
|||
return cachedParseInt(s, 10);
|
||||
};
|
||||
|
||||
var isFirstParty = function(firstPartyDomain, hostname) {
|
||||
if ( hostname.slice(0 - firstPartyDomain.length) !== firstPartyDomain ) {
|
||||
return false;
|
||||
}
|
||||
var isFirstParty = function(domain, hostname) {
|
||||
// Be sure to not confuse 'example.com' with 'anotherexample.com'
|
||||
var c = hostname.charAt(hostname.length - firstPartyDomain.length - 1);
|
||||
return c === '.' || c === '';
|
||||
return hostname.endsWith(domain) &&
|
||||
(hostname.length === domain.length ||
|
||||
hostname.charAt(hostname.length - domain.length - 1) === '.');
|
||||
};
|
||||
|
||||
var isBadRegex = function(s) {
|
||||
|
@ -235,26 +233,25 @@ var hostnameTestPicker = function(owner) {
|
|||
|
||||
// Only one hostname
|
||||
if ( domainOpt.indexOf('|') === -1 ) {
|
||||
return domainOpt.charAt(0) !== '~' ? hostnameHitTest : hostnameMissTest;
|
||||
return domainOpt.startsWith('~') ? hostnameMissTest : hostnameHitTest;
|
||||
}
|
||||
|
||||
// Multiple hostnames: use a dictionary.
|
||||
var dict = owner._hostnameDict = Object.create(null);
|
||||
var hostnames = domainOpt.split('|');
|
||||
var i, hostname;
|
||||
var i, hostname, dict;
|
||||
|
||||
// First find out whether we have a homogeneous dictionary
|
||||
var hit = false, miss = false;
|
||||
i = hostnames.length;
|
||||
while ( i-- ) {
|
||||
if ( hostnames[i].charAt(0) !== '~' ) {
|
||||
hit = true;
|
||||
if ( miss ) {
|
||||
if ( hostnames[i].startsWith('~') ) {
|
||||
miss = true;
|
||||
if ( hit ) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
miss = true;
|
||||
if ( hit ) {
|
||||
hit = true;
|
||||
if ( miss ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -264,40 +261,44 @@ var hostnameTestPicker = function(owner) {
|
|||
// Spotted one occurrence in EasyList Lite (cjxlist.txt):
|
||||
// domain=photobucket.com|~secure.photobucket.com
|
||||
if ( hit && miss ) {
|
||||
dict = owner._hostnameDict = new Map();
|
||||
i = hostnames.length;
|
||||
while ( i-- ) {
|
||||
hostname = hostnames[i];
|
||||
if ( hostname.charAt(0) !== '~' ) {
|
||||
dict[hostname] = true;
|
||||
if ( hostname.startsWith('~') ) {
|
||||
dict.set(hostname.slice(1), false);
|
||||
} else {
|
||||
dict[hostname.slice(1)] = false;
|
||||
dict.set(hostname, true);
|
||||
}
|
||||
}
|
||||
return hostnameMixedSetTest;
|
||||
}
|
||||
|
||||
// Homogeneous dictionary.
|
||||
dict = owner._hostnameDict = new Set();
|
||||
i = hostnames.length;
|
||||
while ( i-- ) {
|
||||
hostname = hostnames[i];
|
||||
if ( hostname.charAt(0) !== '~' ) {
|
||||
dict[hostname] = true;
|
||||
} else {
|
||||
dict[hostname.slice(1)] = true;
|
||||
}
|
||||
dict.add(hostname.startsWith('~') ? hostname.slice(1) : hostname);
|
||||
}
|
||||
|
||||
return hit ? hostnameHitSetTest : hostnameMissSetTest;
|
||||
};
|
||||
|
||||
var hostnameHitTest = function(owner) {
|
||||
var hostname = owner.domainOpt;
|
||||
return pageHostnameRegister.slice(0 - hostname.length) === hostname;
|
||||
var current = pageHostnameRegister;
|
||||
var target = owner.domainOpt;
|
||||
return current.endsWith(target) &&
|
||||
(current.length === target.length ||
|
||||
current.charAt(current.length - target.length - 1) === '.');
|
||||
};
|
||||
|
||||
var hostnameMissTest = function(owner) {
|
||||
var hostname = owner.domainOpt;
|
||||
return pageHostnameRegister.slice(1 - hostname.length) !== hostname.slice(1);
|
||||
var current = pageHostnameRegister;
|
||||
var target = owner.domainOpt;
|
||||
return current.endsWith(target) === false ||
|
||||
(current.length !== target.length &&
|
||||
current.charAt(current.length - target.length - 1) !== '.');
|
||||
};
|
||||
|
||||
var hostnameHitSetTest = function(owner) {
|
||||
|
@ -305,7 +306,7 @@ var hostnameHitSetTest = function(owner) {
|
|||
var needle = pageHostnameRegister;
|
||||
var pos;
|
||||
for (;;) {
|
||||
if ( dict[needle] ) {
|
||||
if ( dict.has(needle) ) {
|
||||
return true;
|
||||
}
|
||||
pos = needle.indexOf('.');
|
||||
|
@ -322,7 +323,7 @@ var hostnameMissSetTest = function(owner) {
|
|||
var needle = pageHostnameRegister;
|
||||
var pos;
|
||||
for (;;) {
|
||||
if ( dict[needle] ) {
|
||||
if ( dict.has(needle) ) {
|
||||
return false;
|
||||
}
|
||||
pos = needle.indexOf('.');
|
||||
|
@ -341,11 +342,11 @@ var hostnameMixedSetTest = function(owner) {
|
|||
var hit = false;
|
||||
var v, pos;
|
||||
for (;;) {
|
||||
v = dict[needle] || undefined;
|
||||
v = dict.get(needle);
|
||||
if ( v === false ) {
|
||||
return false;
|
||||
}
|
||||
if ( v /* === true */ ) {
|
||||
if ( v === true ) {
|
||||
hit = true;
|
||||
}
|
||||
pos = needle.indexOf('.');
|
||||
|
@ -393,7 +394,7 @@ var FilterPlain = function(s, 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 =
|
||||
|
@ -424,8 +425,8 @@ var FilterPlainHostname = function(s, tokenBeg, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
||||
return this.hostnameTest(this) &&
|
||||
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||
return url.startsWith(this.s, tokenBeg - this.tokenBeg) &&
|
||||
this.hostnameTest(this);
|
||||
};
|
||||
|
||||
FilterPlainHostname.fid =
|
||||
|
@ -453,7 +454,7 @@ var FilterPlainPrefix0 = function(s) {
|
|||
};
|
||||
|
||||
FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
|
||||
return url.substr(tokenBeg, this.s.length) === this.s;
|
||||
return url.startsWith(this.s, tokenBeg);
|
||||
};
|
||||
|
||||
FilterPlainPrefix0.fid =
|
||||
|
@ -482,8 +483,8 @@ var FilterPlainPrefix0Hostname = function(s, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||
return this.hostnameTest(this) &&
|
||||
url.substr(tokenBeg, this.s.length) === this.s;
|
||||
return url.startsWith(this.s, tokenBeg) &&
|
||||
this.hostnameTest(this);
|
||||
};
|
||||
|
||||
FilterPlainPrefix0Hostname.fid =
|
||||
|
@ -511,7 +512,7 @@ var FilterPlainPrefix1 = function(s) {
|
|||
};
|
||||
|
||||
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 =
|
||||
|
@ -540,8 +541,8 @@ var FilterPlainPrefix1Hostname = function(s, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
||||
return this.hostnameTest(this) &&
|
||||
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||
return url.startsWith(this.s, tokenBeg - 1) &&
|
||||
this.hostnameTest(this);
|
||||
};
|
||||
|
||||
FilterPlainPrefix1Hostname.fid =
|
||||
|
@ -569,7 +570,7 @@ var FilterPlainLeftAnchored = function(s) {
|
|||
};
|
||||
|
||||
FilterPlainLeftAnchored.prototype.match = function(url) {
|
||||
return url.slice(0, this.s.length) === this.s;
|
||||
return url.startsWith(this.s);
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchored.fid =
|
||||
|
@ -598,8 +599,8 @@ var FilterPlainLeftAnchoredHostname = function(s, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
||||
return this.hostnameTest(this) &&
|
||||
url.slice(0, this.s.length) === this.s;
|
||||
return url.startsWith(this.s) &&
|
||||
this.hostnameTest(this);
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchoredHostname.fid =
|
||||
|
@ -627,7 +628,7 @@ var FilterPlainRightAnchored = function(s) {
|
|||
};
|
||||
|
||||
FilterPlainRightAnchored.prototype.match = function(url) {
|
||||
return url.slice(-this.s.length) === this.s;
|
||||
return url.endsWith(this.s);
|
||||
};
|
||||
|
||||
FilterPlainRightAnchored.fid =
|
||||
|
@ -656,8 +657,8 @@ var FilterPlainRightAnchoredHostname = function(s, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||
return this.hostnameTest(this) &&
|
||||
url.slice(-this.s.length) === this.s;
|
||||
return url.endsWith(this.s) &&
|
||||
this.hostnameTest(this);
|
||||
};
|
||||
|
||||
FilterPlainRightAnchoredHostname.fid =
|
||||
|
@ -688,7 +689,7 @@ var FilterPlainHnAnchored = function(s) {
|
|||
};
|
||||
|
||||
FilterPlainHnAnchored.prototype.match = function(url, tokenBeg) {
|
||||
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
||||
if ( url.startsWith(this.s, tokenBeg) === false ) {
|
||||
return false;
|
||||
}
|
||||
// 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=qBPML7ton0E
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -727,10 +729,10 @@ var FilterPlainHnAnchoredHostname = function(s, domainOpt) {
|
|||
};
|
||||
|
||||
FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
||||
if ( this.hostnameTest(this) === false ) {
|
||||
return false;
|
||||
}
|
||||
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
||||
if (
|
||||
url.startsWith(this.s, tokenBeg) === false ||
|
||||
this.hostnameTest(this) === false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// 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.match = function(url) {
|
||||
if ( this.hostnameTest(this) === false ) {
|
||||
return false;
|
||||
}
|
||||
return FilterGeneric.prototype.match.call(this, url);
|
||||
return this.hostnameTest(this) &&
|
||||
FilterGeneric.prototype.match.call(this, url);
|
||||
};
|
||||
|
||||
FilterGenericHostname.fid =
|
||||
|
@ -884,10 +884,8 @@ FilterGenericHnAnchoredHostname.prototype = Object.create(FilterGenericHnAnchore
|
|||
FilterGenericHnAnchoredHostname.prototype.constructor = FilterGenericHnAnchoredHostname;
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
||||
if ( this.hostnameTest(this) === false ) {
|
||||
return false;
|
||||
}
|
||||
return FilterGenericHnAnchored.prototype.match.call(this, url);
|
||||
return this.hostnameTest(this) &&
|
||||
FilterGenericHnAnchored.prototype.match.call(this, url);
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.fid =
|
||||
|
@ -1004,7 +1002,7 @@ FilterHostnameDict.prototype.cutoff = 250;
|
|||
|
||||
FilterHostnameDict.prototype.meltBucket = function(len, bucket) {
|
||||
var map = {};
|
||||
if ( bucket.charAt(0) === ' ' ) {
|
||||
if ( bucket.startsWith(' ') ) {
|
||||
bucket.trim().split(' ').map(function(k) {
|
||||
map[k] = true;
|
||||
});
|
||||
|
@ -1105,7 +1103,7 @@ FilterHostnameDict.prototype.matchesExactly = function(hn) {
|
|||
if ( typeof bucket === 'object' ) {
|
||||
bucket = this.dict[key] = this.freezeBucket(bucket);
|
||||
}
|
||||
if ( bucket.charAt(0) === ' ' ) {
|
||||
if ( bucket.startsWith(' ') ) {
|
||||
return bucket.indexOf(' ' + hn + ' ') !== -1;
|
||||
}
|
||||
// binary search
|
||||
|
@ -1379,7 +1377,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
|||
var opt, not;
|
||||
for ( var i = 0; i < opts.length; i++ ) {
|
||||
opt = opts[i];
|
||||
not = opt.charAt(0) === '~';
|
||||
not = opt.startsWith('~');
|
||||
if ( not ) {
|
||||
opt = opt.slice(1);
|
||||
}
|
||||
|
@ -1411,7 +1409,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
|||
this.parseOptType(opt, not);
|
||||
continue;
|
||||
}
|
||||
if ( opt.lastIndexOf('domain=', 0) === 0 ) {
|
||||
if ( opt.startsWith('domain=') ) {
|
||||
this.domainOpt = opt.slice(7);
|
||||
continue;
|
||||
}
|
||||
|
@ -1423,7 +1421,7 @@ FilterParser.prototype.parseOptions = function(s) {
|
|||
this.parseOptParty(true, not);
|
||||
continue;
|
||||
}
|
||||
if ( opt.lastIndexOf('redirect=', 0) === 0 ) {
|
||||
if ( opt.startsWith('redirect=') ) {
|
||||
if ( this.action === BlockAction ) {
|
||||
this.redirect = true;
|
||||
continue;
|
||||
|
@ -1466,7 +1464,7 @@ FilterParser.prototype.parse = function(raw) {
|
|||
|
||||
// block or allow filter?
|
||||
// Important: this must be executed before parsing options
|
||||
if ( s.lastIndexOf('@@', 0) === 0 ) {
|
||||
if ( s.startsWith('@@') ) {
|
||||
this.action = AllowAction;
|
||||
s = s.slice(2);
|
||||
}
|
||||
|
@ -1475,7 +1473,7 @@ FilterParser.prototype.parse = function(raw) {
|
|||
// https://github.com/gorhill/uBlock/issues/842
|
||||
// - ensure sure we are not dealing with a regex-based filter.
|
||||
// - lookup the last occurrence of `$`.
|
||||
if ( s.charAt(0) !== '/' || s.slice(-1) !== '/' ) {
|
||||
if ( s.startsWith('/') === false || s.endsWith('/') === false ) {
|
||||
pos = s.lastIndexOf('$');
|
||||
if ( pos !== -1 ) {
|
||||
// https://github.com/gorhill/uBlock/issues/952
|
||||
|
@ -1490,7 +1488,7 @@ FilterParser.prototype.parse = function(raw) {
|
|||
}
|
||||
|
||||
// regex?
|
||||
if ( s.charAt(0) === '/' && s.slice(-1) === '/' && s.length > 2 ) {
|
||||
if ( s.startsWith('/') && s.endsWith('/') && s.length > 2 ) {
|
||||
this.isRegex = true;
|
||||
this.f = s.slice(1, -1);
|
||||
if ( isBadRegex(this.f) ) {
|
||||
|
@ -1505,7 +1503,7 @@ FilterParser.prototype.parse = function(raw) {
|
|||
}
|
||||
|
||||
// hostname-anchored
|
||||
if ( s.lastIndexOf('||', 0) === 0 ) {
|
||||
if ( s.startsWith('||') ) {
|
||||
this.hostnameAnchored = true;
|
||||
s = s.slice(2);
|
||||
|
||||
|
@ -1519,7 +1517,7 @@ FilterParser.prototype.parse = function(raw) {
|
|||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/1096
|
||||
if ( s.charAt(0) === '^' ) {
|
||||
if ( s.startsWith('^') ) {
|
||||
this.unsupported = true;
|
||||
return this;
|
||||
}
|
||||
|
@ -1533,13 +1531,13 @@ FilterParser.prototype.parse = function(raw) {
|
|||
}
|
||||
|
||||
// left-anchored
|
||||
if ( s.charAt(0) === '|' ) {
|
||||
if ( s.startsWith('|') ) {
|
||||
this.anchor = -1;
|
||||
s = s.slice(1);
|
||||
}
|
||||
|
||||
// right-anchored
|
||||
if ( s.slice(-1) === '|' ) {
|
||||
if ( s.endsWith('|') ) {
|
||||
this.anchor = 1;
|
||||
s = s.slice(0, -1);
|
||||
}
|
||||
|
@ -1547,11 +1545,11 @@ FilterParser.prototype.parse = function(raw) {
|
|||
// normalize placeholders
|
||||
if ( this.reHasWildcard.test(s) ) {
|
||||
// remove pointless leading *
|
||||
if ( s.charAt(0) === '*' ) {
|
||||
if ( s.startsWith('*') ) {
|
||||
s = s.replace(/^\*+([^%0-9a-z])/, '$1');
|
||||
}
|
||||
// remove pointless trailing *
|
||||
if ( s.slice(-1) === '*' ) {
|
||||
if ( s.endsWith('*') ) {
|
||||
s = s.replace(/([^%0-9a-z])\*+$/, '$1');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
// https://github.com/gorhill/uBlock/issues/277
|
||||
// uBlock's filter lists are always enabled by default, so we
|
||||
// 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 ) {
|
||||
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
|
||||
// is supported as I suspect we are going to start to see `ws`, `wss`
|
||||
// as well soon.
|
||||
if ( pageStore && tabContext.rawURL.lastIndexOf('http', 0) === 0 ) {
|
||||
if ( pageStore && tabContext.rawURL.startsWith('http') ) {
|
||||
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
|
||||
// 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);
|
||||
if ( matches !== null ) {
|
||||
targetURL = JSON.parse(atob(matches[1])).url;
|
||||
|
|
|
@ -47,7 +47,9 @@ var isHandcraftedWhitelistDirective = function(directive) {
|
|||
var matchWhitelistDirective = function(url, hostname, directive) {
|
||||
// Directive is a plain hostname
|
||||
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
|
||||
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
|
||||
if ( line.charAt(0) === '#' ) {
|
||||
if ( line.startsWith('#') ) {
|
||||
key = '#';
|
||||
directive = line;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ URI.set = function(uri) {
|
|||
}
|
||||
this.hostname = matches[1] !== undefined ? matches[1] : '';
|
||||
// http://en.wikipedia.org/wiki/FQDN
|
||||
if ( this.hostname.slice(-1) === '.' ) {
|
||||
if ( this.hostname.endsWith('.') ) {
|
||||
this.hostname = this.hostname.slice(0, -1);
|
||||
}
|
||||
this.port = matches[2] !== undefined ? matches[2].slice(1) : '';
|
||||
|
@ -271,7 +271,7 @@ URI.hostnameFromURI = function(uri) {
|
|||
}
|
||||
// http://en.wikipedia.org/wiki/FQDN
|
||||
var hostname = matches[1];
|
||||
if ( hostname.slice(-1) === '.' ) {
|
||||
if ( hostname.endsWith('.') ) {
|
||||
hostname = hostname.slice(0, -1);
|
||||
}
|
||||
return hostname.toLowerCase();
|
||||
|
|
|
@ -92,7 +92,7 @@ var indexOfMatch = function(urls, url) {
|
|||
if ( entry.url.length > urlLen ) {
|
||||
continue;
|
||||
}
|
||||
if ( url.lastIndexOf(entry.url, 0) === 0 ) {
|
||||
if ( url.startsWith(entry.url) ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue