mirror of https://github.com/gorhill/uBlock.git
Code review of whitelisting-related code
- Use `Map()` instead of `{}` for internal data structure - Export as array of directives instead of as a string
This commit is contained in:
parent
8e7384ba84
commit
9065bbdd48
|
@ -116,7 +116,7 @@ const µBlock = (function() { // jshint ignore:line
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/180
|
// https://github.com/chrisaljoudi/uBlock/issues/180
|
||||||
// Whitelist directives need to be loaded once the PSL is available
|
// Whitelist directives need to be loaded once the PSL is available
|
||||||
netWhitelist: {},
|
netWhitelist: new Map(),
|
||||||
netWhitelistModifyTime: 0,
|
netWhitelistModifyTime: 0,
|
||||||
netWhitelistDefault: [
|
netWhitelistDefault: [
|
||||||
'about-scheme',
|
'about-scheme',
|
||||||
|
|
|
@ -762,9 +762,9 @@ const µb = µBlock;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
|
|
||||||
var getLocalData = function(callback) {
|
const getLocalData = function(callback) {
|
||||||
var onStorageInfoReady = function(bytesInUse) {
|
const onStorageInfoReady = function(bytesInUse) {
|
||||||
var o = µb.restoreBackupSettings;
|
const o = µb.restoreBackupSettings;
|
||||||
callback({
|
callback({
|
||||||
storageUsed: bytesInUse,
|
storageUsed: bytesInUse,
|
||||||
lastRestoreFile: o.lastRestoreFile,
|
lastRestoreFile: o.lastRestoreFile,
|
||||||
|
@ -779,13 +779,15 @@ var getLocalData = function(callback) {
|
||||||
µb.getBytesInUse(onStorageInfoReady);
|
µb.getBytesInUse(onStorageInfoReady);
|
||||||
};
|
};
|
||||||
|
|
||||||
var backupUserData = function(callback) {
|
const backupUserData = function(callback) {
|
||||||
var userData = {
|
const userData = {
|
||||||
timeStamp: Date.now(),
|
timeStamp: Date.now(),
|
||||||
version: vAPI.app.version,
|
version: vAPI.app.version,
|
||||||
userSettings: µb.userSettings,
|
userSettings: µb.userSettings,
|
||||||
selectedFilterLists: µb.selectedFilterLists,
|
selectedFilterLists: µb.selectedFilterLists,
|
||||||
hiddenSettings: µb.hiddenSettings,
|
hiddenSettings: µb.hiddenSettings,
|
||||||
|
whitelist: µb.arrayFromWhitelist(µb.netWhitelist),
|
||||||
|
// String representation eventually to be deprecated
|
||||||
netWhitelist: µb.stringFromWhitelist(µb.netWhitelist),
|
netWhitelist: µb.stringFromWhitelist(µb.netWhitelist),
|
||||||
dynamicFilteringString: µb.permanentFirewall.toString(),
|
dynamicFilteringString: µb.permanentFirewall.toString(),
|
||||||
urlFilteringString: µb.permanentURLFiltering.toString(),
|
urlFilteringString: µb.permanentURLFiltering.toString(),
|
||||||
|
@ -793,9 +795,9 @@ var backupUserData = function(callback) {
|
||||||
userFilters: ''
|
userFilters: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
var onUserFiltersReady = function(details) {
|
const onUserFiltersReady = function(details) {
|
||||||
userData.userFilters = details.content;
|
userData.userFilters = details.content;
|
||||||
var filename = vAPI.i18n('aboutBackupFilename')
|
const filename = vAPI.i18n('aboutBackupFilename')
|
||||||
.replace('{{datetime}}', µb.dateNowToSensibleString())
|
.replace('{{datetime}}', µb.dateNowToSensibleString())
|
||||||
.replace(/ +/g, '_');
|
.replace(/ +/g, '_');
|
||||||
µb.restoreBackupSettings.lastBackupFile = filename;
|
µb.restoreBackupSettings.lastBackupFile = filename;
|
||||||
|
@ -829,9 +831,19 @@ const restoreUserData = function(request) {
|
||||||
userData.hiddenSettingsString || ''
|
userData.hiddenSettingsString || ''
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// Whitelist directives can be represented as an array or as a
|
||||||
|
// (eventually to be deprecated) string.
|
||||||
|
let whitelist = userData.whitelist;
|
||||||
|
if (
|
||||||
|
Array.isArray(whitelist) === false &&
|
||||||
|
typeof userData.netWhitelist === 'string' &&
|
||||||
|
userData.netWhitelist !== ''
|
||||||
|
) {
|
||||||
|
whitelist = userData.netWhitelist.split('\n');
|
||||||
|
}
|
||||||
vAPI.storage.set({
|
vAPI.storage.set({
|
||||||
hiddenSettings: hiddenSettings,
|
hiddenSettings: hiddenSettings,
|
||||||
netWhitelist: userData.netWhitelist || '',
|
netWhitelist: whitelist || [],
|
||||||
dynamicFilteringString: userData.dynamicFilteringString || '',
|
dynamicFilteringString: userData.dynamicFilteringString || '',
|
||||||
urlFilteringString: userData.urlFilteringString || '',
|
urlFilteringString: userData.urlFilteringString || '',
|
||||||
hostnameSwitchesString: userData.hostnameSwitchesString || '',
|
hostnameSwitchesString: userData.hostnameSwitchesString || '',
|
||||||
|
|
|
@ -50,7 +50,10 @@ const handleImportFilePicker = function() {
|
||||||
if ( typeof userData.userSettings !== 'object' ) {
|
if ( typeof userData.userSettings !== 'object' ) {
|
||||||
throw 'Invalid';
|
throw 'Invalid';
|
||||||
}
|
}
|
||||||
if ( typeof userData.netWhitelist !== 'string' ) {
|
if (
|
||||||
|
Array.isArray(userData.whitelist) === false &&
|
||||||
|
typeof userData.netWhitelist !== 'string'
|
||||||
|
) {
|
||||||
throw 'Invalid';
|
throw 'Invalid';
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -239,7 +239,10 @@ const onVersionReady = function(lastVersion) {
|
||||||
// gorhill 2014-12-15: not anymore
|
// gorhill 2014-12-15: not anymore
|
||||||
|
|
||||||
const onNetWhitelistReady = function(netWhitelistRaw) {
|
const onNetWhitelistReady = function(netWhitelistRaw) {
|
||||||
µb.netWhitelist = µb.whitelistFromString(netWhitelistRaw);
|
if ( typeof netWhitelistRaw === 'string' ) {
|
||||||
|
netWhitelistRaw = netWhitelistRaw.split('\n');
|
||||||
|
}
|
||||||
|
µb.netWhitelist = µb.whitelistFromArray(netWhitelistRaw);
|
||||||
µb.netWhitelistModifyTime = Date.now();
|
µb.netWhitelistModifyTime = Date.now();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,7 +361,7 @@ const createDefaultProps = function() {
|
||||||
'lastRestoreTime': 0,
|
'lastRestoreTime': 0,
|
||||||
'lastBackupFile': '',
|
'lastBackupFile': '',
|
||||||
'lastBackupTime': 0,
|
'lastBackupTime': 0,
|
||||||
'netWhitelist': µb.netWhitelistDefault.join('\n'),
|
'netWhitelist': µb.netWhitelistDefault,
|
||||||
'selfieMagic': 0,
|
'selfieMagic': 0,
|
||||||
'version': '0.0.0.0'
|
'version': '0.0.0.0'
|
||||||
};
|
};
|
||||||
|
|
|
@ -238,7 +238,7 @@
|
||||||
|
|
||||||
µBlock.saveWhitelist = function() {
|
µBlock.saveWhitelist = function() {
|
||||||
vAPI.storage.set({
|
vAPI.storage.set({
|
||||||
netWhitelist: this.stringFromWhitelist(this.netWhitelist)
|
netWhitelist: this.arrayFromWhitelist(this.netWhitelist)
|
||||||
});
|
});
|
||||||
this.netWhitelistModifyTime = Date.now();
|
this.netWhitelistModifyTime = Date.now();
|
||||||
};
|
};
|
||||||
|
@ -1194,8 +1194,11 @@
|
||||||
binNotEmpty = true;
|
binNotEmpty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeof data.netWhitelist === 'string' ) {
|
if ( Array.isArray(data.whitelist) ) {
|
||||||
bin.netWhitelist = data.netWhitelist;
|
bin.netWhitelist = data.whitelist;
|
||||||
|
binNotEmpty = true;
|
||||||
|
} else if ( typeof data.netWhitelist === 'string' ) {
|
||||||
|
bin.netWhitelist = data.netWhitelist.split('\n');
|
||||||
binNotEmpty = true;
|
binNotEmpty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
163
src/js/ublock.js
163
src/js/ublock.js
|
@ -24,29 +24,30 @@
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
(function(){
|
// *****************************************************************************
|
||||||
|
// start of local namespace
|
||||||
|
|
||||||
/******************************************************************************/
|
{
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/405
|
// https://github.com/chrisaljoudi/uBlock/issues/405
|
||||||
// Be more flexible with whitelist syntax
|
// Be more flexible with whitelist syntax
|
||||||
|
|
||||||
// Any special regexp char will be escaped
|
// Any special regexp char will be escaped
|
||||||
var whitelistDirectiveEscape = /[-\/\\^$+?.()|[\]{}]/g;
|
const whitelistDirectiveEscape = /[-\/\\^$+?.()|[\]{}]/g;
|
||||||
|
|
||||||
// All `*` will be expanded into `.*`
|
// All `*` will be expanded into `.*`
|
||||||
var whitelistDirectiveEscapeAsterisk = /\*/g;
|
const whitelistDirectiveEscapeAsterisk = /\*/g;
|
||||||
|
|
||||||
// Remember encountered regexps for reuse.
|
// Remember encountered regexps for reuse.
|
||||||
var directiveToRegexpMap = new Map();
|
const directiveToRegexpMap = new Map();
|
||||||
|
|
||||||
// Probably manually entered whitelist directive
|
// Probably manually entered whitelist directive
|
||||||
var isHandcraftedWhitelistDirective = function(directive) {
|
const isHandcraftedWhitelistDirective = function(directive) {
|
||||||
return directive.startsWith('/') && directive.endsWith('/') ||
|
return directive.startsWith('/') && directive.endsWith('/') ||
|
||||||
directive.indexOf('/') !== -1 && directive.indexOf('*') !== -1;
|
directive.indexOf('/') !== -1 && directive.indexOf('*') !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
var matchDirective = function(url, hostname, directive) {
|
const matchDirective = function(url, hostname, directive) {
|
||||||
// Directive is a plain hostname.
|
// Directive is a plain hostname.
|
||||||
if ( directive.indexOf('/') === -1 ) {
|
if ( directive.indexOf('/') === -1 ) {
|
||||||
return hostname.endsWith(directive) &&
|
return hostname.endsWith(directive) &&
|
||||||
|
@ -54,13 +55,16 @@ var matchDirective = function(url, hostname, directive) {
|
||||||
hostname.charAt(hostname.length - directive.length - 1) === '.');
|
hostname.charAt(hostname.length - directive.length - 1) === '.');
|
||||||
}
|
}
|
||||||
// Match URL exactly.
|
// Match URL exactly.
|
||||||
if ( directive.startsWith('/') === false && directive.indexOf('*') === -1 ) {
|
if (
|
||||||
|
directive.startsWith('/') === false &&
|
||||||
|
directive.indexOf('*') === -1
|
||||||
|
) {
|
||||||
return url === directive;
|
return url === directive;
|
||||||
}
|
}
|
||||||
// Transpose into a regular expression.
|
// Transpose into a regular expression.
|
||||||
var re = directiveToRegexpMap.get(directive);
|
let re = directiveToRegexpMap.get(directive);
|
||||||
if ( re === undefined ) {
|
if ( re === undefined ) {
|
||||||
var reStr;
|
let reStr;
|
||||||
if ( directive.startsWith('/') && directive.endsWith('/') ) {
|
if ( directive.startsWith('/') && directive.endsWith('/') ) {
|
||||||
reStr = directive.slice(1, -1);
|
reStr = directive.slice(1, -1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,9 +77,9 @@ var matchDirective = function(url, hostname, directive) {
|
||||||
return re.test(url);
|
return re.test(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
var matchBucket = function(url, hostname, bucket, start) {
|
const matchBucket = function(url, hostname, bucket, start) {
|
||||||
if ( bucket ) {
|
if ( bucket ) {
|
||||||
for ( var i = start || 0, n = bucket.length; i < n; i++ ) {
|
for ( let i = start || 0, n = bucket.length; i < n; i++ ) {
|
||||||
if ( matchDirective(url, hostname, bucket[i]) ) {
|
if ( matchDirective(url, hostname, bucket[i]) ) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -84,23 +88,20 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://www.youtube.com/watch?v=RL2W_XK-UJ4&list=PLhPp-QAUKF_hRMjWsYvvdazGw0qIjtSXJ
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.getNetFilteringSwitch = function(url) {
|
µBlock.getNetFilteringSwitch = function(url) {
|
||||||
var targetHostname = this.URI.hostnameFromURI(url),
|
const hostname = this.URI.hostnameFromURI(url);
|
||||||
key = targetHostname,
|
let key = hostname;
|
||||||
pos;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ( matchBucket(url, targetHostname, this.netWhitelist[key]) !== -1 ) {
|
if ( matchBucket(url, hostname, this.netWhitelist.get(key)) !== -1 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pos = key.indexOf('.');
|
const pos = key.indexOf('.');
|
||||||
if ( pos === -1 ) { break; }
|
if ( pos === -1 ) { break; }
|
||||||
key = key.slice(pos + 1);
|
key = key.slice(pos + 1);
|
||||||
}
|
}
|
||||||
if ( matchBucket(url, targetHostname, this.netWhitelist['//']) !== -1 ) {
|
if ( matchBucket(url, hostname, this.netWhitelist.get('//')) !== -1 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -109,7 +110,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.toggleNetFilteringSwitch = function(url, scope, newState) {
|
µBlock.toggleNetFilteringSwitch = function(url, scope, newState) {
|
||||||
var currentState = this.getNetFilteringSwitch(url);
|
const currentState = this.getNetFilteringSwitch(url);
|
||||||
if ( newState === undefined ) {
|
if ( newState === undefined ) {
|
||||||
newState = !currentState;
|
newState = !currentState;
|
||||||
}
|
}
|
||||||
|
@ -117,58 +118,59 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
var netWhitelist = this.netWhitelist,
|
const netWhitelist = this.netWhitelist;
|
||||||
pos = url.indexOf('#'),
|
const pos = url.indexOf('#');
|
||||||
targetURL = pos !== -1 ? url.slice(0, pos) : url,
|
let targetURL = pos !== -1 ? url.slice(0, pos) : url;
|
||||||
targetHostname = this.URI.hostnameFromURI(targetURL),
|
const targetHostname = this.URI.hostnameFromURI(targetURL);
|
||||||
key = targetHostname,
|
let key = targetHostname;
|
||||||
directive = scope === 'page' ? targetURL : targetHostname;
|
let directive = scope === 'page' ? targetURL : targetHostname;
|
||||||
|
|
||||||
// Add to directive list
|
// Add to directive list
|
||||||
if ( newState === false ) {
|
if ( newState === false ) {
|
||||||
if ( netWhitelist[key] === undefined ) {
|
let bucket = netWhitelist.get(key);
|
||||||
netWhitelist[key] = [];
|
if ( bucket === undefined ) {
|
||||||
|
bucket = [];
|
||||||
|
netWhitelist.set(key, bucket);
|
||||||
}
|
}
|
||||||
netWhitelist[key].push(directive);
|
bucket.push(directive);
|
||||||
this.saveWhitelist();
|
this.saveWhitelist();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove from directive list whatever causes current URL to be whitelisted
|
// Remove all directives which cause current URL to be whitelisted
|
||||||
var bucket, i;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bucket = netWhitelist[key];
|
const bucket = netWhitelist.get(key);
|
||||||
if ( bucket !== undefined ) {
|
if ( bucket !== undefined ) {
|
||||||
i = undefined;
|
let i;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
i = matchBucket(targetURL, targetHostname, bucket, i);
|
i = matchBucket(targetURL, targetHostname, bucket, i);
|
||||||
if ( i === -1 ) { break; }
|
if ( i === -1 ) { break; }
|
||||||
directive = bucket.splice(i, 1)[0];
|
directive = bucket.splice(i, 1)[0];
|
||||||
if ( isHandcraftedWhitelistDirective(directive) ) {
|
if ( isHandcraftedWhitelistDirective(directive) ) {
|
||||||
netWhitelist['#'].push('# ' + directive);
|
netWhitelist.get('#').push(`# ${directive}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket.length === 0 ) {
|
if ( bucket.length === 0 ) {
|
||||||
delete netWhitelist[key];
|
netWhitelist.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos = key.indexOf('.');
|
const pos = key.indexOf('.');
|
||||||
if ( pos === -1 ) { break; }
|
if ( pos === -1 ) { break; }
|
||||||
key = key.slice(pos + 1);
|
key = key.slice(pos + 1);
|
||||||
}
|
}
|
||||||
bucket = netWhitelist['//'];
|
const bucket = netWhitelist.get('//');
|
||||||
if ( bucket !== undefined ) {
|
if ( bucket !== undefined ) {
|
||||||
i = undefined;
|
let i;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
i = matchBucket(targetURL, targetHostname, bucket, i);
|
i = matchBucket(targetURL, targetHostname, bucket, i);
|
||||||
if ( i === -1 ) { break; }
|
if ( i === -1 ) { break; }
|
||||||
directive = bucket.splice(i, 1)[0];
|
directive = bucket.splice(i, 1)[0];
|
||||||
if ( isHandcraftedWhitelistDirective(directive) ) {
|
if ( isHandcraftedWhitelistDirective(directive) ) {
|
||||||
netWhitelist['#'].push('# ' + directive);
|
netWhitelist.get('#').push(`# ${directive}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket.length === 0 ) {
|
if ( bucket.length === 0 ) {
|
||||||
delete netWhitelist['//'];
|
netWhitelist.delete('//');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.saveWhitelist();
|
this.saveWhitelist();
|
||||||
|
@ -179,8 +181,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
|
|
||||||
µBlock.arrayFromWhitelist = function(whitelist) {
|
µBlock.arrayFromWhitelist = function(whitelist) {
|
||||||
const out = new Set();
|
const out = new Set();
|
||||||
for ( const key in whitelist ) {
|
for ( const bucket of whitelist.values() ) {
|
||||||
const bucket = whitelist[key];
|
|
||||||
for ( const directive of bucket ) {
|
for ( const directive of bucket ) {
|
||||||
out.add(directive);
|
out.add(directive);
|
||||||
}
|
}
|
||||||
|
@ -194,25 +195,23 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.whitelistFromString = function(s) {
|
µBlock.whitelistFromArray = function(lines) {
|
||||||
var whitelist = Object.create(null),
|
const whitelist = new Map();
|
||||||
lineIter = new this.LineIterator(s),
|
|
||||||
line, matches, key, directive, re;
|
|
||||||
|
|
||||||
// Comment bucket must always be ready to be used.
|
// Comment bucket must always be ready to be used.
|
||||||
whitelist['#'] = [];
|
whitelist.set('#', []);
|
||||||
|
|
||||||
// New set of directives, scrap cached data.
|
// New set of directives, scrap cached data.
|
||||||
directiveToRegexpMap.clear();
|
directiveToRegexpMap.clear();
|
||||||
|
|
||||||
while ( !lineIter.eot() ) {
|
for ( let line of lines ) {
|
||||||
line = lineIter.next().trim();
|
line = line.trim();
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/171
|
// https://github.com/gorhill/uBlock/issues/171
|
||||||
// Skip empty lines
|
// Skip empty lines
|
||||||
if ( line === '' ) {
|
if ( line === '' ) { continue; }
|
||||||
continue;
|
|
||||||
}
|
let key, 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.startsWith('#') ) {
|
if ( line.startsWith('#') ) {
|
||||||
|
@ -229,11 +228,15 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Regex-based (ensure it is valid)
|
// Regex-based (ensure it is valid)
|
||||||
else if ( line.length > 2 && line.startsWith('/') && line.endsWith('/') ) {
|
else if (
|
||||||
|
line.length > 2 &&
|
||||||
|
line.startsWith('/') &&
|
||||||
|
line.endsWith('/')
|
||||||
|
) {
|
||||||
key = '//';
|
key = '//';
|
||||||
directive = line;
|
directive = line;
|
||||||
try {
|
try {
|
||||||
re = new RegExp(directive.slice(1, -1));
|
const re = new RegExp(directive.slice(1, -1));
|
||||||
directiveToRegexpMap.set(directive, re);
|
directiveToRegexpMap.set(directive, re);
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
key = '#';
|
key = '#';
|
||||||
|
@ -244,7 +247,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
// label (or else it would be just impossible to make an efficient
|
// label (or else it would be just impossible to make an efficient
|
||||||
// dict.
|
// dict.
|
||||||
else {
|
else {
|
||||||
matches = this.reWhitelistHostnameExtractor.exec(line);
|
const matches = this.reWhitelistHostnameExtractor.exec(line);
|
||||||
if ( !matches || matches.length !== 2 ) {
|
if ( !matches || matches.length !== 2 ) {
|
||||||
key = '#';
|
key = '#';
|
||||||
directive = '# ' + line;
|
directive = '# ' + line;
|
||||||
|
@ -260,21 +263,28 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
|
|
||||||
// Be sure this stays fixed:
|
// Be sure this stays fixed:
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/185
|
// https://github.com/chrisaljoudi/uBlock/issues/185
|
||||||
if ( whitelist[key] === undefined ) {
|
let bucket = whitelist.get(key);
|
||||||
whitelist[key] = [];
|
if ( bucket === undefined ) {
|
||||||
|
bucket = [];
|
||||||
|
whitelist.set(key, bucket);
|
||||||
}
|
}
|
||||||
whitelist[key].push(directive);
|
bucket.push(directive);
|
||||||
}
|
}
|
||||||
return whitelist;
|
return whitelist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
µBlock.whitelistFromString = function(s) {
|
||||||
|
return this.whitelistFromArray(s.split('\n'));
|
||||||
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3717
|
// https://github.com/gorhill/uBlock/issues/3717
|
||||||
µBlock.reWhitelistBadHostname = /[^a-z0-9.\-_\[\]:]/;
|
µBlock.reWhitelistBadHostname = /[^a-z0-9.\-_\[\]:]/;
|
||||||
µBlock.reWhitelistHostnameExtractor = /([a-z0-9.\-_\[\]]+)(?::[\d*]+)?\/(?:[^\x00-\x20\/]|$)[^\x00-\x20]*$/;
|
µBlock.reWhitelistHostnameExtractor = /([a-z0-9.\-_\[\]]+)(?::[\d*]+)?\/(?:[^\x00-\x20\/]|$)[^\x00-\x20]*$/;
|
||||||
|
|
||||||
/******************************************************************************/
|
// end of local namespace
|
||||||
|
// *****************************************************************************
|
||||||
|
|
||||||
})();
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -391,7 +401,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
// https://www.reddit.com/r/uBlockOrigin/comments/8524cf/my_custom_scriptlets_doesnt_work_what_am_i_doing/
|
// https://www.reddit.com/r/uBlockOrigin/comments/8524cf/my_custom_scriptlets_doesnt_work_what_am_i_doing/
|
||||||
|
|
||||||
µBlock.changeHiddenSettings = function(hs) {
|
µBlock.changeHiddenSettings = function(hs) {
|
||||||
var mustReloadResources =
|
const mustReloadResources =
|
||||||
hs.userResourcesLocation !== this.hiddenSettings.userResourcesLocation;
|
hs.userResourcesLocation !== this.hiddenSettings.userResourcesLocation;
|
||||||
this.hiddenSettings = hs;
|
this.hiddenSettings = hs;
|
||||||
this.saveHiddenSettings();
|
this.saveHiddenSettings();
|
||||||
|
@ -522,7 +532,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'no-large-media':
|
case 'no-large-media':
|
||||||
var pageStore = this.pageStoreFromTabId(details.tabId);
|
const pageStore = this.pageStoreFromTabId(details.tabId);
|
||||||
if ( pageStore !== null ) {
|
if ( pageStore !== null ) {
|
||||||
pageStore.temporarilyAllowLargeMediaElements(!details.state);
|
pageStore.temporarilyAllowLargeMediaElements(!details.state);
|
||||||
}
|
}
|
||||||
|
@ -560,43 +570,44 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.scriptlets = (function() {
|
µBlock.scriptlets = (function() {
|
||||||
var pendingEntries = new Map();
|
const pendingEntries = new Map();
|
||||||
|
|
||||||
var Entry = function(tabId, scriptlet, callback) {
|
const Entry = class {
|
||||||
|
constructor(tabId, scriptlet, callback) {
|
||||||
this.tabId = tabId;
|
this.tabId = tabId;
|
||||||
this.scriptlet = scriptlet;
|
this.scriptlet = scriptlet;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.timer = vAPI.setTimeout(this.service.bind(this), 1000);
|
this.timer = vAPI.setTimeout(this.service.bind(this), 1000);
|
||||||
};
|
}
|
||||||
|
service(response) {
|
||||||
Entry.prototype.service = function(response) {
|
|
||||||
if ( this.timer !== null ) {
|
if ( this.timer !== null ) {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
}
|
}
|
||||||
pendingEntries.delete(makeKey(this.tabId, this.scriptlet));
|
pendingEntries.delete(makeKey(this.tabId, this.scriptlet));
|
||||||
this.callback(response);
|
this.callback(response);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeKey = function(tabId, scriptlet) {
|
const makeKey = function(tabId, scriptlet) {
|
||||||
return tabId + ' ' + scriptlet;
|
return tabId + ' ' + scriptlet;
|
||||||
};
|
};
|
||||||
|
|
||||||
var report = function(tabId, scriptlet, response) {
|
const report = function(tabId, scriptlet, response) {
|
||||||
var key = makeKey(tabId, scriptlet);
|
const key = makeKey(tabId, scriptlet);
|
||||||
var entry = pendingEntries.get(key);
|
const entry = pendingEntries.get(key);
|
||||||
if ( entry === undefined ) { return; }
|
if ( entry === undefined ) { return; }
|
||||||
entry.service(response);
|
entry.service(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
var inject = function(tabId, scriptlet, callback) {
|
const inject = function(tabId, scriptlet, callback) {
|
||||||
if ( typeof callback === 'function' ) {
|
if ( typeof callback === 'function' ) {
|
||||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var key = makeKey(tabId, scriptlet),
|
const key = makeKey(tabId, scriptlet);
|
||||||
entry = pendingEntries.get(key);
|
const entry = pendingEntries.get(key);
|
||||||
if ( entry !== undefined ) {
|
if ( entry !== undefined ) {
|
||||||
if ( callback !== entry.callback ) {
|
if ( callback !== entry.callback ) {
|
||||||
callback();
|
callback();
|
||||||
|
@ -611,7 +622,7 @@ var matchBucket = function(url, hostname, bucket, start) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: think about a callback mechanism.
|
// TODO: think about a callback mechanism.
|
||||||
var injectDeep = function(tabId, scriptlet) {
|
const injectDeep = function(tabId, scriptlet) {
|
||||||
vAPI.tabs.injectScript(tabId, {
|
vAPI.tabs.injectScript(tabId, {
|
||||||
file: '/js/scriptlets/' + scriptlet + '.js',
|
file: '/js/scriptlets/' + scriptlet + '.js',
|
||||||
allFrames: true
|
allFrames: true
|
||||||
|
|
Loading…
Reference in New Issue