this fixes #6

This commit is contained in:
gorhill 2014-07-25 16:12:20 -04:00
parent a71b9b4712
commit fe372e9a11
13 changed files with 374 additions and 176 deletions

View File

@ -12,16 +12,23 @@ div > p:first-child {
div > p:last-child {
margin-bottom: 0;
}
body > ul {
margin: 0.5em 0 0 0;
padding-left: 1em;
}
ul {
padding: 0;
list-style-type: none;
}
ul > li {
margin: 0.5em 0 3px 0;
margin: 0.5em 0 0 0;
padding: 0;
font-size: 15px;
list-style-type: none;
}
ul > li > ul {
margin: 0.25em 0 0 0;
}
ul > li > ul > li {
font-size: 14px;
margin: 0 0 0 1em;
@ -35,12 +42,18 @@ ul > li > ul > li {
height: 16em;
white-space: nowrap;
}
#externalLists {
font-size: smaller;
width: 48em;
height: 8em;
white-space: nowrap;
}
</style>
</head>
<body>
<ul id="options" style="margin:0.5em 0 0 0;padding-left:1em;list-style-type:none">
<ul id="options">
<li><button id="blacklistsApply" disabled="true" data-i18n="3pApplyChanges"></button>
<li style="margin-top:0.75em"><input type="checkbox" id="parseAllABPHideFilters"><label data-i18n="3pParseAllABPHideFiltersPrompt1"></label>
<span class="dim" id="3pParseAllABPHideFiltersPrompt2"></span>
@ -48,9 +61,15 @@ ul > li > ul > li {
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
<li style="margin-top:0.75em"><p id="listsOfBlockedHostsPrompt"></p>
</ul>
<ul id="lists" style="margin:0.5em 0 0 0;padding-left:1em;list-style-type:none">
<ul id="lists">
</ul>
<div style="margin: 2em 0 0 2em">
<p data-i18n="3pExternalListsHint" style="margin: 0 0 0.25em 0; font-size: 13px;"></p>
<textarea id="externalLists"></textarea>
<p style="margin: 0.25em 0 0 0"><button id="externalListsApply" disabled="true" data-i18n="3pExternalListsApply"></button></p>
</div>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/dashboard-common.js"></script>

View File

@ -131,6 +131,18 @@
"message":"Regions, languages",
"description":"English: Regions, languages"
},
"3pGroupCustom":{
"message":"Custom",
"description":"English: Custom"
},
"3pExternalListsHint":{
"message":"One URL per line. Lines prefixed with &lsquo;!&rsquo; will be ignored. Invalid URLs will be silently ignored.",
"description":"English: One URL per line. Lines prefixed with &lsquo;!&rsquo; will be ignored. Invalid URLs will be silently ignored."
},
"3pExternalListsApply":{
"message":"Apply",
"description":"English: Apply"
},
"1pFormatHint":{
"message":"One filter per line. A filter can be a plain hostname, or an Adblock Plus-compatible filter. Lines prefixed with &lsquo;!&rsquo; will be ignored.",
"description":"English: One filter per line. A filter can be a plain hostname, or an Adblock Plus-compatible filter. Lines prefixed with &lsquo;!&rsquo; will be ignored."

View File

@ -24,6 +24,7 @@
www.zerohedge.com##.similar-box
# https://github.com/gorhill/uBlock/issues/57
# https://github.com/gorhill/uBlock/issues/98
# New filter class: entity filters, where
# entity = domain minus public suffix
# The following filters were taken out of EasyList and given an entity name,

View File

@ -48,7 +48,7 @@ a {
display: none;
border: 1px dotted black;
background-color: #F8F8F8;
font-size: 90%;
font-size: 13px;
}
.whatisthis-expandable > p {
margin-top: 1em;

View File

@ -28,12 +28,13 @@
/******************************************************************************/
var userListName = chrome.i18n.getMessage('1pPageName');
var selectedBlacklistsHash = '';
var listURLPrefix = 'asset-viewer.html?url=';
var listDetails = {};
var parseCosmeticFilters = true;
var externalLists = '';
/******************************************************************************/
messaging.start('lists.js');
messaging.start('3p-filters.js');
var onMessage = function(msg) {
switch ( msg.what ) {
@ -67,8 +68,6 @@ var renderNumber = function(value) {
var renderBlacklists = function() {
// empty list first
uDom('#lists .listDetails').remove();
var µb = getµb();
uDom('#listsOfBlockedHostsPrompt').text(
@ -111,19 +110,22 @@ var renderBlacklists = function() {
var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats');
var htmlFromBranch = function(groupKey, listKeys, lists) {
listKeys.sort(function(a, b) {
return lists[a].title.localeCompare(lists[b].title);
});
var html = [
'<li>',
chrome.i18n.getMessage('3pGroup' + groupKey.charAt(0).toUpperCase() + groupKey.slice(1)),
'<ul>'
];
if ( !listKeys ) {
return html.join('');
}
listKeys.sort(function(a, b) {
return lists[a].title.localeCompare(lists[b].title);
});
var listEntryTemplate = [
'<li class="listDetails">',
'<input type="checkbox" {{checked}}>',
'&thinsp;',
'<a href="', listURLPrefix, '{{URL}}" type="text/plain">',
'<a href="{{URL}}" type="text/plain">',
'{{name}}',
'</a>',
': ',
@ -140,7 +142,7 @@ var renderBlacklists = function() {
.replace('{{URL}}', encodeURI(listKey))
.replace('{{name}}', htmlFromListName(list.title, listKey))
.replace('{{used}}', !list.off && !isNaN(+list.entryUsedCount) ? renderNumber(list.entryUsedCount) : '0')
.replace('{{total}}', !isNaN(+list.entryCount) ? renderNumber(list.entryCount) : '?')
.replace('{{total}}', !isNaN(+list.entryCount) ? renderNumber(list.entryCount) : '?');
html.push(listEntry);
}
html.push('</ul>');
@ -164,9 +166,13 @@ var renderBlacklists = function() {
return groups;
};
var onListsReceived = function(details) {
listDetails = details;
var lists = details.available;
var html = [];
var groups = groupsFromLists(µb.remoteBlacklists);
var groupKey;
var groups = groupsFromLists(lists);
var groupKey, i;
var groupKeys = [
'default',
'ads',
@ -174,48 +180,70 @@ var renderBlacklists = function() {
'malware',
'social',
'multipurpose',
'regions'
'regions',
'custom'
];
for ( var i = 0; i < groupKeys.length; i++ ) {
for ( i = 0; i < groupKeys.length; i++ ) {
groupKey = groupKeys[i];
html.push(htmlFromBranch(groupKey, groups[groupKey], µb.remoteBlacklists));
html.push(htmlFromBranch(groupKey, groups[groupKey], lists));
delete groups[groupKey];
}
// For all groups not covered above (if any left)
groupKeys = Object.keys(groups);
for ( var i = 0; i < groupKeys.length; i++ ) {
for ( i = 0; i < groupKeys.length; i++ ) {
groupKey = groupKeys[i];
html.push(htmlFromBranch(groupKey, groups[groupKey], µb.remoteBlacklists));
html.push(htmlFromBranch(groupKey, groups[groupKey], lists));
delete groups[groupKey];
}
uDom('#lists .listDetails').remove();
uDom('#lists').html(html.join(''));
uDom('#parseAllABPHideFilters').prop('checked', µb.userSettings.parseAllABPHideFilters === true);
uDom('#parseAllABPHideFilters').prop('checked', listDetails.cosmetic === true);
uDom('#ubiquitousParseAllABPHideFiltersPrompt2').text(
chrome.i18n.getMessage("listsParseAllABPHideFiltersPrompt2")
.replace('{{abpHideFilterCount}}', renderNumber(µb.abpHideFilters.getFilterCount()))
);
uDom('a').attr('target', '_blank');
selectedBlacklistsHash = getSelectedBlacklistsHash();
selectedBlacklistsChanged();
};
messaging.ask({ what: 'getLists' }, onListsReceived);
};
/******************************************************************************/
// Create a hash so that we know whether the selection of preset blacklists
// has changed.
// Check whether lists need reloading.
var getSelectedBlacklistsHash = function() {
var hash = '';
var inputs = uDom('#lists .listDetails > input');
var i = inputs.length();
while ( i-- ) {
hash += inputs.subset(i).prop('checked').toString();
var needToReload = function() {
if ( listDetails.cosmetic !== getµb().userSettings.parseAllABPHideFilters ) {
return true;
}
// Factor in whether cosmetic filters are to be processed
hash += uDom('#parseAllABPHideFilters').prop('checked').toString();
return hash;
var availableLists = listDetails.available;
var currentLists = listDetails.current;
var location, availableOff, currentOff;
// This check existing entries
for ( location in availableLists ) {
if ( availableLists.hasOwnProperty(location) === false ) {
continue;
}
availableOff = availableLists[location].off === true;
currentOff = currentLists[location] === undefined || currentLists[location].off === true;
if ( availableOff !== currentOff ) {
return true;
}
}
// This check removed entries
for ( location in currentLists ) {
if ( currentLists.hasOwnProperty(location) === false ) {
continue;
}
currentOff = currentLists[location].off === true;
availableOff = availableLists[location] === undefined || availableLists[location].off === true;
if ( availableOff !== currentOff ) {
return true;
}
}
return false;
};
/******************************************************************************/
@ -223,10 +251,21 @@ var getSelectedBlacklistsHash = function() {
// This is to give a visual hint that the selection of blacklists has changed.
var selectedBlacklistsChanged = function() {
uDom('#blacklistsApply').prop(
'disabled',
getSelectedBlacklistsHash() === selectedBlacklistsHash
);
uDom('#blacklistsApply').prop('disabled', !needToReload());
};
/******************************************************************************/
var onListCheckboxChanged = function() {
var href = uDom(this).parent().find('a').first().attr('href');
if ( typeof href !== 'string' ) {
return;
}
if ( listDetails.available[href] === undefined ) {
return;
}
listDetails.available[href].off = !this.checked;
selectedBlacklistsChanged();
};
/******************************************************************************/
@ -242,11 +281,16 @@ var onListLinkClicked = function(ev) {
/******************************************************************************/
var blacklistsApplyHandler = function() {
var newHash = getSelectedBlacklistsHash();
if ( newHash === selectedBlacklistsHash ) {
if ( !needToReload() ) {
return;
}
// Reload blacklists
messaging.tell({
what: 'userSettings',
name: 'parseAllABPHideFilters',
value: parseCosmeticFilters
});
// Reload blacklists
var switches = [];
var lis = uDom('#lists .listDetails');
var i = lis.length();
@ -255,8 +299,7 @@ var blacklistsApplyHandler = function() {
path = lis
.subset(i)
.find('a')
.attr('href')
.replace(listURLPrefix, '');
.attr('href');
switches.push({
location: path,
off: lis.subset(i).find('input').prop('checked') === false
@ -266,30 +309,61 @@ var blacklistsApplyHandler = function() {
what: 'reloadAllFilters',
switches: switches
});
uDom('#blacklistsApply').prop('disabled', true );
uDom('#blacklistsApply').prop('disabled', true);
};
/******************************************************************************/
var abpHideFiltersCheckboxChanged = function() {
listDetails.cosmetic = this.checked;
selectedBlacklistsChanged();
};
/******************************************************************************/
var renderExternalLists = function() {
var onReceived = function(details) {
uDom('#externalLists').val(details);
externalLists = details;
};
messaging.ask({ what: 'userSettings', name: 'externalLists' }, onReceived);
};
/******************************************************************************/
var externalListsChangeHandler = function() {
uDom('#externalListsApply').prop(
'disabled',
this.value.trim() === externalLists
);
};
/******************************************************************************/
var externalListsApplyHandler = function() {
externalLists = uDom('#externalLists').val();
messaging.tell({
what: 'userSettings',
name: 'parseAllABPHideFilters',
value: this.checked
name: 'externalLists',
value: externalLists
});
selectedBlacklistsChanged();
renderBlacklists();
uDom('#externalListsApply').prop('disabled', true);
};
/******************************************************************************/
uDom.onLoad(function() {
// Handle user interaction
uDom('#lists').on('change', '.listDetails', selectedBlacklistsChanged);
uDom('#lists').on('click', '.listDetails > a:first-child', onListLinkClicked);
uDom('#blacklistsApply').on('click', blacklistsApplyHandler);
uDom('#parseAllABPHideFilters').on('change', abpHideFiltersCheckboxChanged);
uDom('#blacklistsApply').on('click', blacklistsApplyHandler);
uDom('#lists').on('change', '.listDetails > input', onListCheckboxChanged);
uDom('#lists').on('click', '.listDetails > a:nth-of-type(1)', onListLinkClicked);
uDom('#externalLists').on('input', externalListsChangeHandler);
uDom('#externalListsApply').on('click', externalListsApplyHandler);
renderBlacklists();
renderExternalLists();
});
/******************************************************************************/

View File

@ -122,7 +122,7 @@ var getUpdateList = function(callback) {
}
};
µBlock.assets.getRemote('assets/checksums.txt', onRemoteChecksumsLoaded);
µBlock.assets.getRepo('assets/checksums.txt', onRemoteChecksumsLoaded);
µBlock.assets.get('assets/checksums.txt', onLocalChecksumsLoaded);
};
@ -200,6 +200,9 @@ var update = function(list, callback) {
processList();
};
// Purge obsolete external assets
µBlock.assets.purge(/^https?:\/\/.+$/, Date.now() - µBlock.updateAssetsEvery);
if ( list ) {
processList();
} else {

View File

@ -146,7 +146,7 @@ var cachedAssetsManager = (function() {
};
var onEntries = function(entries) {
if ( entries[path] === undefined ) {
entries[path] = true;
entries[path] = Date.now();
bin.cached_asset_entries = entries;
}
chrome.storage.local.set(bin, onSaved);
@ -154,7 +154,7 @@ var cachedAssetsManager = (function() {
getEntries(onEntries);
};
exports.remove = function(pattern) {
exports.remove = function(pattern, before) {
var onEntries = function(entries) {
var keystoRemove = [];
var paths = Object.keys(entries);
@ -168,6 +168,9 @@ var cachedAssetsManager = (function() {
if ( pattern instanceof RegExp && !pattern.test(path) ) {
continue;
}
if ( typeof before === 'number' && entries[path] >= before ) {
continue;
}
keystoRemove.push(cachedAssetPathPrefix + path);
delete entries[path];
}
@ -406,7 +409,9 @@ var readLocalFile = function(path, callback) {
/******************************************************************************/
var readRemoteFile = function(path, callback) {
// Get the repository copy of a built-in asset.
var readRepoFile = function(path, callback) {
var reportBack = function(content, err) {
var details = {
'path': path,
@ -416,8 +421,8 @@ var readRemoteFile = function(path, callback) {
callback(details);
};
var onRemoteFileLoaded = function() {
// console.log('µBlock> readRemoteFile() / onRemoteFileLoaded()');
var onRepoFileLoaded = function() {
// console.log('µBlock> readRepoFile() / onRepoFileLoaded()');
// https://github.com/gorhill/httpswitchboard/issues/263
if ( this.status === 200 ) {
reportBack(this.responseText);
@ -427,8 +432,8 @@ var readRemoteFile = function(path, callback) {
this.onload = this.onerror = null;
};
var onRemoteFileError = function(ev) {
console.error('µBlock> readRemoteFile() / onRemoteFileError("%s")', path);
var onRepoFileError = function(ev) {
console.error('µBlock> readRepoFile() / onRepoFileError("%s")', path);
reportBack('', 'Error');
this.onload = this.onerror = null;
};
@ -436,13 +441,64 @@ var readRemoteFile = function(path, callback) {
// 'ublock=...' is to skip browser cache
getTextFileFromURL(
repositoryRoot + path + '?ublock=' + Date.now(),
onRemoteFileLoaded,
onRemoteFileError
onRepoFileLoaded,
onRepoFileError
);
};
/******************************************************************************/
var readExternalFile = function(path, callback) {
var reportBack = function(content, err) {
var details = {
'path': path,
'content': content
};
if ( err ) {
details.error = err;
}
callback(details);
};
var onExternalFileCached = function(details) {
this.onload = this.onerror = null;
// console.log('µBlock> onExternalFileCached()');
reportBack(details.content);
};
var onExternalFileLoaded = function() {
this.onload = this.onerror = null;
// console.log('µBlock> onExternalFileLoaded()');
cachedAssetsManager.save(path, this.responseText, onExternalFileCached);
};
var onExternalFileError = function(ev) {
console.error('µBlock> onExternalFileError() / onLocalFileError("%s")', path);
reportBack('', 'Error');
this.onload = this.onerror = null;
};
var onCachedContentLoaded = function(details) {
// console.log('µBlock> readLocalFile() / onCacheFileLoaded()');
reportBack(details.content);
};
var onCachedContentError = function(details) {
// console.error('µBlock> readLocalFile() / onCacheFileError("%s")', path);
getTextFileFromURL(details.path, onExternalFileLoaded, onExternalFileError);
};
cachedAssetsManager.load(path, onCachedContentLoaded, onCachedContentError);
};
/******************************************************************************/
var purgeCache = function(pattern, before) {
cachedAssetsManager.remove(pattern, before);
};
/******************************************************************************/
var writeLocalFile = function(path, content, callback) {
cachedAssetsManager.save(path, content, callback);
};
@ -580,7 +636,9 @@ synchronizeCache();
return {
'get': readLocalFile,
'getRemote': readRemoteFile,
'getExternal': readExternalFile,
'getRepo': readRepoFile,
'purge': purgeCache,
'put': writeLocalFile,
'update': updateFromRemote
};

View File

@ -32,6 +32,7 @@ return {
userSettings: {
collapseBlocked: true,
externalLists: '',
logBlockedRequests: false,
logAllowedRequests: false,
parseAllABPHideFilters: true,
@ -47,13 +48,12 @@ return {
projectServerRoot: 'https://raw.githubusercontent.com/gorhill/uBlock/master/',
userFiltersPath: 'assets/user/filters.txt',
// list of remote blacklist locations
remoteBlacklists: {
// permanent lists
permanentLists: {
// User
'assets/user/filters.txt': {
group: 'default'
},
// uBlock
'assets/ublock/filters.txt': {
title: 'µBlock filters',
@ -64,7 +64,10 @@ return {
title: 'µBlock filters - Privacy',
group: 'default'
}
// 3rd-party lists fetched dynamically
},
// current lists
remoteBlacklists: {
},
pageStores: {},

View File

@ -36,7 +36,7 @@
var InvalidCharacterError = function(message) {
this.message = message;
};
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype = new Error();
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
if (!CSS.escape) {

View File

@ -233,11 +233,28 @@ var onMessage = function(request, sender, callback) {
(function() {
var getLists = function(callback) {
var µb = µBlock;
var onReceived = function(lists) {
callback({
available: lists,
current: µb.remoteBlacklists,
cosmetic: µb.userSettings.parseAllABPHideFilters
});
};
µb.getAvailableLists(onReceived);
};
/******************************************************************************/
var onMessage = function(request, sender, callback) {
var µb = µBlock;
// Async
switch ( request.what ) {
case 'getLists':
return getLists(callback);
case 'readUserUbiquitousBlockRules':
return µb.assets.get(µb.userFiltersPath, callback);

View File

@ -138,6 +138,9 @@ function defaultHandler(request, sender, callback) {
// Async
switch ( request.what ) {
case 'getAssetContent':
if ( /^https?:\/\//.test(request.url) ) {
return µBlock.assets.getExternal(request.url, callback);
}
return µBlock.assets.get(request.url, callback);
case 'loadUbiquitousAllowRules':

View File

@ -154,7 +154,7 @@ PageStore.prototype.updateBadge = function() {
var iconStr = '';
if ( µb.userSettings.showIconBadge && netFilteringSwitch && this.perLoadBlockedRequestCount ) {
iconStr = µb.formatCount(this.perLoadBlockedRequestCount);
iconStr = this.perLoadBlockedRequestCount.toLocaleString();
}
chrome.browserAction.setBadgeText({
tabId: this.tabId,

View File

@ -124,33 +124,100 @@
/******************************************************************************/
µBlock.loadUbiquitousBlacklists = function() {
var blacklistLoadCount;
var obsoleteBlacklists = [];
µBlock.getAvailableLists = function(callback) {
var availableLists = {};
var removeObsoleteBlacklistsHandler = function(store) {
if ( !store.remoteBlacklists ) {
return;
}
// selected lists
var onSelectedListsLoaded = function(store) {
var lists = store.remoteBlacklists;
var locations = Object.keys(lists);
var location;
while ( location = obsoleteBlacklists.pop() ) {
delete store.remoteBlacklists[location];
while ( location = locations.pop() ) {
if ( !availableLists[location] ) {
continue;
}
chrome.storage.local.set(store);
// https://github.com/gorhill/httpswitchboard/issues/218
// Transfer potentially existing list title into restored list data.
if ( lists[location].title !== availableLists[location].title ) {
lists[location].title = availableLists[location].title;
}
availableLists[location] = lists[location];
}
callback(availableLists);
};
var removeObsoleteBlacklists = function() {
if ( obsoleteBlacklists.length === 0 ) {
return;
// built-in lists
var onBuiltinListsLoaded = function(details) {
var location, locations;
try {
locations = JSON.parse(details.content);
} catch (e) {
locations = {};
}
for ( location in locations ) {
if ( locations.hasOwnProperty(location) === false ) {
continue;
}
availableLists['assets/thirdparties/' + location] = locations[location];
}
// Now get user's selection of lists
chrome.storage.local.get(
{ 'remoteBlacklists': µBlock.remoteBlacklists },
removeObsoleteBlacklistsHandler
{ 'remoteBlacklists': availableLists },
onSelectedListsLoaded
);
};
// permanent lists
var location;
var lists = this.permanentLists;
for ( location in lists ) {
if ( lists.hasOwnProperty(location) === false ) {
continue;
}
availableLists[location] = lists[location];
}
// custom lists
var c;
var locations = this.userSettings.externalLists.split('\n');
for ( var i = 0; i < locations.length; i++ ) {
location = locations[i].trim();
c = location.charAt(0);
if ( location === '' || c === '!' || c === '#' ) {
continue;
}
// Coarse validation
if ( /[^0-9A-Za-z!*'();:@&=+$,\/?%#\[\]_.~-]/.test(location) ) {
continue;
}
availableLists[location] = {
title: '',
group: 'custom',
external: true
};
}
// get built-in block lists.
this.assets.get('assets/ublock/filter-lists.json', onBuiltinListsLoaded);
};
/******************************************************************************/
µBlock.loadUbiquitousBlacklists = function() {
var µb = this;
var blacklistLoadCount;
var loadBlacklistsEnd = function() {
µb.abpFilters.freeze();
µb.abpHideFilters.freeze();
µb.messaging.announce({ what: 'loadUbiquitousBlacklistCompleted' });
chrome.storage.local.set({ 'remoteBlacklists': µb.remoteBlacklists });
};
var mergeBlacklist = function(details) {
var µb = µBlock;
µb.mergeUbiquitousBlacklist(details);
blacklistLoadCount -= 1;
if ( blacklistLoadCount === 0 ) {
@ -158,97 +225,38 @@
}
};
var loadBlacklistsEnd = function() {
µBlock.abpFilters.freeze();
µBlock.abpHideFilters.freeze();
removeObsoleteBlacklists();
µBlock.messaging.announce({ what: 'loadUbiquitousBlacklistCompleted' });
};
var loadBlacklistsStart = function(store) {
var µb = µBlock;
var loadBlacklistsStart = function(lists) {
µb.remoteBlacklists = lists;
// rhill 2013-12-10: set all existing entries to `false`.
µb.abpFilters.reset();
µb.abpHideFilters.reset();
var storedLists = store.remoteBlacklists;
var storedListLocations = Object.keys(storedLists);
blacklistLoadCount = storedListLocations.length;
var locations = Object.keys(lists);
blacklistLoadCount = locations.length;
if ( blacklistLoadCount === 0 ) {
loadBlacklistsEnd();
return;
}
// Backward compatibility for when a list changes location
var relocations = [
{
// https://github.com/gorhill/httpswitchboard/issues/361
'bad': 'assets/thirdparties/adblock-czechoslovaklist.googlecode.com/svn/filters.txt',
'good': 'assets/thirdparties/raw.githubusercontent.com/tomasko126/easylistczechandslovak/master/filters.txt'
}
];
var relocation;
while ( relocation = relocations.pop() ) {
if ( µb.remoteBlacklists[relocation.good] && storedLists[relocation.bad] ) {
storedLists[relocation.good].off = storedLists[relocation.bad].off;
}
}
// Load each preset blacklist which is not disabled.
var location;
while ( location = storedListLocations.pop() ) {
// If loaded list location is not part of default list locations,
// remove its entry from local storage.
if ( !µb.remoteBlacklists[location] ) {
obsoleteBlacklists.push(location);
blacklistLoadCount -= 1;
continue;
}
// https://github.com/gorhill/httpswitchboard/issues/218
// Transfer potentially existing list title into restored list data.
if ( storedLists[location].title !== µb.remoteBlacklists[location].title ) {
storedLists[location].title = µb.remoteBlacklists[location].title;
}
// Store details of this preset blacklist
µb.remoteBlacklists[location] = storedLists[location];
while ( location = locations.pop() ) {
// rhill 2013-12-09:
// Ignore list if disabled
// https://github.com/gorhill/httpswitchboard/issues/78
if ( storedLists[location].off ) {
if ( lists[location].off ) {
blacklistLoadCount -= 1;
continue;
}
if ( /^https?:\/\/.+$/.test(location) ) {
µb.assets.getExternal(location, mergeBlacklist);
} else {
µb.assets.get(location, mergeBlacklist);
}
}
};
var onListOfBlockListsLoaded = function(details) {
var µb = µBlock;
// Initialize built-in list of 3rd-party block lists.
var lists = JSON.parse(details.content);
for ( var location in lists ) {
if ( lists.hasOwnProperty(location) === false ) {
continue;
}
µb.remoteBlacklists['assets/thirdparties/' + location] = lists[location];
}
// Now get user's selection of list of block lists.
chrome.storage.local.get(
{ 'remoteBlacklists': µb.remoteBlacklists },
loadBlacklistsStart
);
};
// Reset list of 3rd-party block lists.
for ( var location in this.remoteBlacklists ) {
if ( location.indexOf('assets/thirdparties/') === 0 ) {
delete this.remoteBlacklists[location];
}
}
// Get new list of 3rd-party block lists.
this.assets.get('assets/ublock/filter-lists.json', onListOfBlockListsLoaded);
this.getAvailableLists(loadBlacklistsStart);
};
/******************************************************************************/