1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-15 15:32:28 +02:00

code review: modernize old code

This commit is contained in:
Raymond Hill 2018-04-05 15:22:19 -04:00
parent c1d3b6222e
commit c0387835fa
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 78 additions and 118 deletions

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill Copyright (C) 2014-2018 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -755,7 +755,7 @@ FilterContainer.prototype.compileHostnameSelector = function(
var compiled = µb.staticExtFilteringEngine.compileSelector(parsed.suffix); var compiled = µb.staticExtFilteringEngine.compileSelector(parsed.suffix);
if ( compiled === undefined ) { return; } if ( compiled === undefined ) { return; }
var domain = this.µburi.domainFromHostname(hostname), var domain = this.µburi.domainFromHostnameNoCache(hostname),
hash; hash;
// https://github.com/chrisaljoudi/uBlock/issues/188 // https://github.com/chrisaljoudi/uBlock/issues/188

View File

@ -960,11 +960,18 @@
}; };
var onCompiledListLoaded = function(details) { var onCompiledListLoaded = function(details) {
if ( details.content === '' ) { var selfie;
try {
selfie = JSON.parse(details.content);
} catch (ex) {
}
if (
selfie === undefined ||
publicSuffixList.fromSelfie(selfie) === false
) {
µb.assets.get(assetKey, onRawListLoaded); µb.assets.get(assetKey, onRawListLoaded);
return; return;
} }
publicSuffixList.fromSelfie(JSON.parse(details.content));
callback(); callback();
}; };

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 Raymond Hill Copyright (C) 2014-2018 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -299,6 +299,10 @@ URI.domainFromHostname = function(hostname) {
return domainCacheAdd(hostname, hostname); return domainCacheAdd(hostname, hostname);
}; };
URI.domainFromHostnameNoCache = function(hostname) {
return reIPAddressNaive.test(hostname) ? hostname : psl.getDomain(hostname);
};
URI.domain = function() { URI.domain = function() {
return this.domainFromHostname(this.hostname); return this.domainFromHostname(this.hostname);
}; };
@ -328,11 +332,11 @@ URI.pathFromURI = function(uri) {
// specific set of hostnames within a narrow time span -- in other words, I // specific set of hostnames within a narrow time span -- in other words, I
// believe probability of cache hit are high in uBlock. // believe probability of cache hit are high in uBlock.
var domainCache = Object.create(null); var domainCache = new Map();
var domainCacheCount = 0; var domainCacheCountLowWaterMark = 40;
var domainCacheCountLowWaterMark = 35; var domainCacheCountHighWaterMark = 60;
var domainCacheCountHighWaterMark = 50; var domainCacheEntryJunkyardMax =
var domainCacheEntryJunkyardMax = domainCacheCountHighWaterMark - domainCacheCountLowWaterMark; domainCacheCountHighWaterMark - domainCacheCountLowWaterMark;
var DomainCacheEntry = function(domain) { var DomainCacheEntry = function(domain) {
this.init(domain); this.init(domain);
@ -352,23 +356,20 @@ DomainCacheEntry.prototype.dispose = function() {
}; };
var domainCacheEntryFactory = function(domain) { var domainCacheEntryFactory = function(domain) {
var entry = domainCacheEntryJunkyard.pop(); return domainCacheEntryJunkyard.length !== 0 ?
if ( entry ) { domainCacheEntryJunkyard.pop().init(domain) :
return entry.init(domain); new DomainCacheEntry(domain);
}
return new DomainCacheEntry(domain);
}; };
var domainCacheEntryJunkyard = []; var domainCacheEntryJunkyard = [];
var domainCacheAdd = function(hostname, domain) { var domainCacheAdd = function(hostname, domain) {
var entry = domainCache[hostname]; var entry = domainCache.get(hostname);
if ( entry !== undefined ) { if ( entry !== undefined ) {
entry.tstamp = Date.now(); entry.tstamp = Date.now();
} else { } else {
domainCache[hostname] = domainCacheEntryFactory(domain); domainCache.set(hostname, domainCacheEntryFactory(domain));
domainCacheCount += 1; if ( domainCache.size === domainCacheCountHighWaterMark ) {
if ( domainCacheCount === domainCacheCountHighWaterMark ) {
domainCachePrune(); domainCachePrune();
} }
} }
@ -376,29 +377,24 @@ var domainCacheAdd = function(hostname, domain) {
}; };
var domainCacheEntrySort = function(a, b) { var domainCacheEntrySort = function(a, b) {
return domainCache[b].tstamp - domainCache[a].tstamp; return domainCache.get(b).tstamp - domainCache.get(a).tstamp;
}; };
var domainCachePrune = function() { var domainCachePrune = function() {
var hostnames = Object.keys(domainCache) var hostnames = Array.from(domainCache.keys())
.sort(domainCacheEntrySort) .sort(domainCacheEntrySort)
.slice(domainCacheCountLowWaterMark); .slice(domainCacheCountLowWaterMark);
var i = hostnames.length; var i = hostnames.length;
domainCacheCount -= i;
var hostname;
while ( i-- ) { while ( i-- ) {
hostname = hostnames[i]; var hostname = hostnames[i];
domainCache[hostname].dispose(); domainCache.get(hostname).dispose();
delete domainCache[hostname]; domainCache.delete(hostname);
} }
}; };
var domainCacheReset = function() { window.addEventListener('publicSuffixList', function() {
domainCache = Object.create(null); domainCache.clear();
domainCacheCount = 0; });
};
psl.onChanged.addListener(domainCacheReset);
/******************************************************************************/ /******************************************************************************/

View File

@ -2,7 +2,7 @@
publicsuffixlist.js - an efficient javascript implementation to deal with publicsuffixlist.js - an efficient javascript implementation to deal with
Mozilla Foundation's Public Suffix List <http://publicsuffix.org/list/> Mozilla Foundation's Public Suffix List <http://publicsuffix.org/list/>
Copyright (C) 2013 Raymond Hill Copyright (C) 2013-2018 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -37,9 +37,8 @@
/******************************************************************************/ /******************************************************************************/
var exceptions = {}; var exceptions = new Map();
var rules = {}; var rules = new Map();
var selfieMagic = 'iscjsfsaolnm';
// This value dictate how the search will be performed: // This value dictate how the search will be performed:
// < this.cutoffLength = indexOf() // < this.cutoffLength = indexOf()
@ -47,8 +46,6 @@ var selfieMagic = 'iscjsfsaolnm';
var cutoffLength = 256; var cutoffLength = 256;
var mustPunycode = /[^a-z0-9.-]/; var mustPunycode = /[^a-z0-9.-]/;
var onChangedListeners = [];
/******************************************************************************/ /******************************************************************************/
// In the context of this code, a domain is defined as: // In the context of this code, a domain is defined as:
@ -127,20 +124,17 @@ function search(store, hostname) {
tld = hostname.slice(pos + 1); tld = hostname.slice(pos + 1);
remainder = hostname.slice(0, pos); remainder = hostname.slice(0, pos);
} }
var substore = store[tld]; var substore = store.get(tld);
if ( !substore ) { if ( substore === undefined ) { return false; }
return false;
}
// If substore is a string, use indexOf() // If substore is a string, use indexOf()
if ( typeof substore === 'string' ) { if ( typeof substore === 'string' ) {
return substore.indexOf(' ' + remainder + ' ') >= 0; return substore.indexOf(' ' + remainder + ' ') >= 0;
} }
// It is an array: use binary search. // It is an array: use binary search.
var l = remainder.length; var l = remainder.length;
if ( l >= substore.length ) { return false; }
var haystack = substore[l]; var haystack = substore[l];
if ( !haystack ) { if ( haystack.length === 0 ) { return false; }
return false;
}
var left = 0; var left = 0;
var right = Math.floor(haystack.length / l + 0.5); var right = Math.floor(haystack.length / l + 0.5);
var i, needle; var i, needle;
@ -168,8 +162,8 @@ function search(store, hostname) {
// Suggestion: use <https://github.com/bestiejs/punycode.js> it's quite good. // Suggestion: use <https://github.com/bestiejs/punycode.js> it's quite good.
function parse(text, toAscii) { function parse(text, toAscii) {
exceptions = {}; exceptions = new Map();
rules = {}; rules = new Map();
// http://publicsuffix.org/list/: // http://publicsuffix.org/list/:
// "... all rules must be canonicalized in the normal way // "... all rules must be canonicalized in the normal way
@ -229,16 +223,18 @@ function parse(text, toAscii) {
} }
// Store suffix using tld as key // Store suffix using tld as key
if ( !store.hasOwnProperty(tld) ) { var substore = store.get(tld);
store[tld] = []; if ( substore === undefined ) {
store.set(tld, (substore = []));
} }
if ( line ) { if ( line ) {
store[tld].push(line); substore.push(line);
} }
} }
crystallize(exceptions); crystallize(exceptions);
crystallize(rules); crystallize(rules);
callListeners(onChangedListeners);
window.dispatchEvent(new CustomEvent('publicSuffixList'));
} }
/******************************************************************************/ /******************************************************************************/
@ -247,107 +243,69 @@ function parse(text, toAscii) {
// for future look up. // for future look up.
function crystallize(store) { function crystallize(store) {
var suffixes, suffix, i, l; for ( var entry of store ) {
var tld = entry[0];
for ( var tld in store ) { var suffixes = entry[1];
if ( !store.hasOwnProperty(tld) ) {
continue;
}
suffixes = store[tld].join(' ');
// No suffix // No suffix
if ( !suffixes ) { if ( suffixes.length === 0 ) {
store[tld] = ''; store.set(tld, '');
continue; continue;
} }
// Concatenated list of suffixes less than cutoff length: // Concatenated list of suffixes less than cutoff length:
// Store as string, lookup using indexOf() // Store as string, lookup using indexOf()
if ( suffixes.length < cutoffLength ) { var s = suffixes.join(' ');
store[tld] = ' ' + suffixes + ' '; if ( s.length < cutoffLength ) {
store.set(tld, ' ' + s + ' ');
continue; continue;
} }
// Concatenated list of suffixes greater or equal to cutoff length // Concatenated list of suffixes greater or equal to cutoff length
// Store as array keyed on suffix length, lookup using binary search. // Store as array keyed on suffix length, lookup using binary search.
// I borrowed the idea to key on string length here: // I borrowed the idea to key on string length here:
// http://ejohn.org/blog/dictionary-lookups-in-javascript/#comment-392072 // http://ejohn.org/blog/dictionary-lookups-in-javascript/#comment-392072
var i = suffixes.length, l;
i = store[tld].length; var aa = [];
suffixes = [];
while ( i-- ) { while ( i-- ) {
suffix = store[tld][i]; var suffix = suffixes[i];
var j = aa.length;
l = suffix.length; l = suffix.length;
if ( !suffixes[l] ) { while ( j <= l ) {
suffixes[l] = []; aa[j] = []; j += 1;
} }
suffixes[l].push(suffix); aa[l].push(suffix);
} }
l = suffixes.length; l = aa.length;
while ( l-- ) { while ( l-- ) {
if ( suffixes[l] ) { aa[l] = aa[l].sort().join('');
suffixes[l] = suffixes[l].sort().join('');
}
} }
store[tld] = suffixes; store.set(tld, aa);
} }
return store; return store;
} }
/******************************************************************************/ /******************************************************************************/
var selfieMagic = 1;
function toSelfie() { function toSelfie() {
return { return {
magic: selfieMagic, magic: selfieMagic,
rules: rules, rules: Array.from(rules),
exceptions: exceptions exceptions: Array.from(exceptions)
}; };
} }
function fromSelfie(selfie) { function fromSelfie(selfie) {
if ( typeof selfie !== 'object' || typeof selfie.magic !== 'string' || selfie.magic !== selfieMagic ) { if ( typeof selfie !== 'object' || selfie.magic !== selfieMagic ) {
return false; return false;
} }
rules = selfie.rules; rules = new Map(selfie.rules);
exceptions = selfie.exceptions; exceptions = new Map(selfie.exceptions);
callListeners(onChangedListeners); window.dispatchEvent(new CustomEvent('publicSuffixList'));
return true; return true;
} }
/******************************************************************************/ /******************************************************************************/
var addListener = function(listeners, callback) {
if ( typeof callback !== 'function' ) {
return;
}
if ( listeners.indexOf(callback) === -1 ) {
listeners.push(callback);
}
};
var removeListener = function(listeners, callback) {
var pos = listeners.indexOf(callback);
if ( pos !== -1 ) {
listeners.splice(pos, 1);
}
};
var callListeners = function(listeners) {
for ( var i = 0; i < listeners.length; i++ ) {
listeners[i]();
}
};
/******************************************************************************/
var onChanged = {
addListener: function(callback) {
addListener(onChangedListeners, callback);
},
removeListener: function(callback) {
removeListener(onChangedListeners, callback);
}
};
/******************************************************************************/
// Public API // Public API
root = root || window; root = root || window;
@ -359,7 +317,6 @@ root.publicSuffixList = {
'getPublicSuffix': getPublicSuffix, 'getPublicSuffix': getPublicSuffix,
'toSelfie': toSelfie, 'toSelfie': toSelfie,
'fromSelfie': fromSelfie, 'fromSelfie': fromSelfie,
'onChanged': onChanged
}; };
/******************************************************************************/ /******************************************************************************/