This commit is contained in:
gorhill 2015-03-10 23:46:18 -04:00
parent afa08caa6a
commit 39ad1585e9
8 changed files with 346 additions and 163 deletions

View file

@ -12,7 +12,7 @@
<button id="buttonApply" class="custom reloadAll disabled" data-i18n="3pApplyChanges"></button> <button id="buttonApply" class="custom reloadAll disabled" data-i18n="3pApplyChanges"></button>
<ul id="options"> <ul id="options">
<li><input type="checkbox" id="autoUpdate"><label data-i18n="3pAutoUpdatePrompt1" for="autoUpdate"></label> <li><input type="checkbox" id="autoUpdate"><label data-i18n="3pAutoUpdatePrompt1" for="autoUpdate"></label>&ensp;
<button class="custom reloadAll disabled" id="buttonUpdate" data-i18n="3pUpdateNow"></button> <button class="custom reloadAll disabled" id="buttonUpdate" data-i18n="3pUpdateNow"></button>
<button id="buttonPurgeAll" class="custom disabled" data-i18n="3pPurgeAll"></button> <button id="buttonPurgeAll" class="custom disabled" data-i18n="3pPurgeAll"></button>
<li><input type="checkbox" id="parseCosmeticFilters"><label data-i18n="3pParseAllABPHideFiltersPrompt1" for="parseCosmeticFilters"></label> <li><input type="checkbox" id="parseCosmeticFilters"><label data-i18n="3pParseAllABPHideFiltersPrompt1" for="parseCosmeticFilters"></label>
@ -28,7 +28,11 @@
<p style="margin: 0.25em 0 0 0"><button id="externalListsApply" disabled="true" data-i18n="3pExternalListsApply"></button></p> <p style="margin: 0.25em 0 0 0"><button id="externalListsApply" disabled="true" data-i18n="3pExternalListsApply"></button></p>
</div> </div>
<div id="busyOverlay"></div> <div id="busyOverlay">
<div></div>
<!-- progress bar widget -->
<div><div></div><div></div></div>
</div>
<div id="templates" style="display: none;"> <div id="templates" style="display: none;">
<ul> <ul>

View file

@ -128,17 +128,63 @@ body[dir=rtl] #externalListsDiv {
word-wrap: normal; word-wrap: normal;
} }
body #busyOverlay { body #busyOverlay {
position: fixed; background-color: transparent;
top: 0;
right: 0;
bottom: 0; bottom: 0;
left: 0;
background-color: white;
opacity: 0.5;
cursor: wait; cursor: wait;
display: none; display: none;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 1000; z-index: 1000;
} }
body.busy #busyOverlay { body.busy #busyOverlay {
display: block; display: block;
} }
#busyOverlay > div:nth-of-type(1) {
background-color: white;
bottom: 0;
left: 0;
opacity: 0.75;
position: absolute;
right: 0;
top: 0;
}
#busyOverlay > div:nth-of-type(2) {
background-color: #eee;
border: 1px solid transparent;
border-color: #80b3ff #80b3ff hsl(216, 100%, 75%);
border-radius: 3px;
box-sizing: border-box;
height: 3em;
left: 10%;
position: absolute;
bottom: 75%;
width: 80%;
}
#busyOverlay > div:nth-of-type(2) > div:nth-of-type(1) {
background-color: hsl(216, 100%, 75%);
background-image: linear-gradient(#a8cbff, #80b3ff);
background-repeat: repeat-x;
border: 0;
box-sizing: border-box;
color: #222;
height: 100%;
left: 0;
padding: 0;
position: absolute;
width: 25%;
}
#busyOverlay > div:nth-of-type(2) > div:nth-of-type(2) {
background-color: transparent;
border: 0;
box-sizing: border-box;
height: 100%;
left: 0;
line-height: 3em;
overflow: hidden;
position: absolute;
text-align: center;
top: 0;
width: 100%;
}

View file

@ -42,7 +42,14 @@ var hasCachedContent = false;
var onMessage = function(msg) { var onMessage = function(msg) {
switch ( msg.what ) { switch ( msg.what ) {
case 'allFilterListsReloaded': case 'allFilterListsReloaded':
renderBlacklists(); renderFilterLists();
break;
case 'forceUpdateAssetsProgress':
renderBusyOverlay(true, msg.progress);
if ( msg.done ) {
messager.send({ what: 'reloadAllFilters' });
}
break; break;
default: default:
@ -62,13 +69,12 @@ var renderNumber = function(value) {
// TODO: get rid of background page dependencies // TODO: get rid of background page dependencies
var renderBlacklists = function() { var renderFilterLists = function() {
uDom('body').toggleClass('busy', true);
var listGroupTemplate = uDom('#templates .groupEntry'); var listGroupTemplate = uDom('#templates .groupEntry');
var listEntryTemplate = uDom('#templates .listEntry'); var listEntryTemplate = uDom('#templates .listEntry');
var listStatsTemplate = vAPI.i18n('3pListsOfBlockedHostsPerListStats'); var listStatsTemplate = vAPI.i18n('3pListsOfBlockedHostsPerListStats');
var renderElapsedTimeToString = vAPI.i18n.renderElapsedTimeToString; var renderElapsedTimeToString = vAPI.i18n.renderElapsedTimeToString;
var lastUpdateString = vAPI.i18n('3pLastUpdate');
// Assemble a pretty blacklist name if possible // Assemble a pretty blacklist name if possible
var listNameFromListKey = function(listKey) { var listNameFromListKey = function(listKey) {
@ -130,7 +136,7 @@ var renderBlacklists = function() {
if ( asset.cached ) { if ( asset.cached ) {
elem = li.descendants('span.status.purge'); elem = li.descendants('span.status.purge');
elem.css('display', ''); elem.css('display', '');
elem.attr('title', renderElapsedTimeToString(asset.lastModified)); elem.attr('title', lastUpdateString.replace('{{ago}}', renderElapsedTimeToString(asset.lastModified)));
hasCachedContent = true; hasCachedContent = true;
} }
return li; return li;
@ -212,7 +218,8 @@ var renderBlacklists = function() {
uDom('#autoUpdate').prop('checked', listDetails.autoUpdate === true); uDom('#autoUpdate').prop('checked', listDetails.autoUpdate === true);
uDom('#parseCosmeticFilters').prop('checked', listDetails.cosmetic === true); uDom('#parseCosmeticFilters').prop('checked', listDetails.cosmetic === true);
updateWidgets(); renderWidgets();
renderBusyOverlay(details.manualUpdate, details.manualUpdateProgress);
}; };
messager.send({ what: 'getLists' }, onListsReceived); messager.send({ what: 'getLists' }, onListsReceived);
@ -220,18 +227,52 @@ var renderBlacklists = function() {
/******************************************************************************/ /******************************************************************************/
// Progress must be normalized to [0, 1], or can be undefined.
var renderBusyOverlay = function(state, progress) {
progress = progress || {};
var showProgress = typeof progress.value === 'number';
if ( showProgress ) {
uDom('#busyOverlay > div:nth-of-type(2) > div:first-child').css(
'width',
(progress.value * 100).toFixed(1) + '%'
);
var text = progress.text || '';
if ( text !== '' ) {
uDom('#busyOverlay > div:nth-of-type(2) > div:last-child').text(text);
}
}
uDom('#busyOverlay > div:nth-of-type(2)').css('display', showProgress ? '' : 'none');
uDom('body').toggleClass('busy', !!state);
};
/******************************************************************************/
// This is to give a visual hint that the selection of blacklists has changed.
var renderWidgets = function() {
uDom('#buttonApply').toggleClass('disabled', !listsSelectionChanged());
uDom('#buttonUpdate').toggleClass('disabled', !listsContentChanged());
uDom('#buttonPurgeAll').toggleClass('disabled', !hasCachedContent);
};
/******************************************************************************/
// Return whether selection of lists changed. // Return whether selection of lists changed.
var listsSelectionChanged = function() { var listsSelectionChanged = function() {
if ( listDetails.cosmetic !== cosmeticSwitch ) { if ( listDetails.cosmetic !== cosmeticSwitch ) {
return true; return true;
} }
if ( cacheWasPurged ) { if ( cacheWasPurged ) {
return true; return true;
} }
var availableLists = listDetails.available; var availableLists = listDetails.available;
var currentLists = listDetails.current; var currentLists = listDetails.current;
var location, availableOff, currentOff; var location, availableOff, currentOff;
// This check existing entries // This check existing entries
for ( location in availableLists ) { for ( location in availableLists ) {
if ( availableLists.hasOwnProperty(location) === false ) { if ( availableLists.hasOwnProperty(location) === false ) {
@ -243,6 +284,7 @@ var listsSelectionChanged = function() {
return true; return true;
} }
} }
// This check removed entries // This check removed entries
for ( location in currentLists ) { for ( location in currentLists ) {
if ( currentLists.hasOwnProperty(location) === false ) { if ( currentLists.hasOwnProperty(location) === false ) {
@ -254,6 +296,7 @@ var listsSelectionChanged = function() {
return true; return true;
} }
} }
return false; return false;
}; };
@ -267,17 +310,6 @@ var listsContentChanged = function() {
/******************************************************************************/ /******************************************************************************/
// This is to give a visual hint that the selection of blacklists has changed.
var updateWidgets = function() {
uDom('#buttonApply').toggleClass('disabled', !listsSelectionChanged());
uDom('#buttonUpdate').toggleClass('disabled', !listsContentChanged());
uDom('#buttonPurgeAll').toggleClass('disabled', !hasCachedContent);
uDom('body').toggleClass('busy', false);
};
/******************************************************************************/
var onListCheckboxChanged = function() { var onListCheckboxChanged = function() {
var href = uDom(this).parent().descendants('a').first().attr('href'); var href = uDom(this).parent().descendants('a').first().attr('href');
if ( typeof href !== 'string' ) { if ( typeof href !== 'string' ) {
@ -287,7 +319,7 @@ var onListCheckboxChanged = function() {
return; return;
} }
listDetails.available[href].off = !this.checked; listDetails.available[href].off = !this.checked;
updateWidgets(); renderWidgets();
}; };
/******************************************************************************/ /******************************************************************************/
@ -317,24 +349,21 @@ var onPurgeClicked = function() {
button.remove(); button.remove();
if ( li.descendants('input').first().prop('checked') ) { if ( li.descendants('input').first().prop('checked') ) {
cacheWasPurged = true; cacheWasPurged = true;
updateWidgets(); renderWidgets();
} }
}; };
/******************************************************************************/ /******************************************************************************/
var reloadAll = function(update) { var selectFilterLists = function(callback) {
// Loading may take a while when resources are fetched from remote // Cosmetic filtering switch
// servers. We do not want the user to force reload while we are reloading.
uDom('body').toggleClass('busy', true);
// Reload blacklists
messager.send({ messager.send({
what: 'userSettings', what: 'userSettings',
name: 'parseAllABPHideFilters', name: 'parseAllABPHideFilters',
value: listDetails.cosmetic value: listDetails.cosmetic
}); });
// Reload blacklists
// Filter lists
var switches = []; var switches = [];
var lis = uDom('#lists .listEntry'); var lis = uDom('#lists .listEntry');
var i = lis.length; var i = lis.length;
@ -349,18 +378,30 @@ var reloadAll = function(update) {
off: lis.subset(i, 1).descendants('input').prop('checked') === false off: lis.subset(i, 1).descendants('input').prop('checked') === false
}); });
} }
messager.send({ messager.send({
what: 'reloadAllFilters', what: 'selectFilterLists',
switches: switches, switches: switches
update: update }, callback);
});
cacheWasPurged = false;
}; };
/******************************************************************************/ /******************************************************************************/
var buttonApplyHandler = function() { var buttonApplyHandler = function() {
reloadAll(false); renderBusyOverlay(true);
var onReloadDone = function() {
messager.send({ what: 'reloadAllFilters' });
};
var onSelectionDone = function() {
messager.send({ what: 'reloadAllFilters' }, onReloadDone);
};
selectFilterLists(onSelectionDone);
cacheWasPurged = false;
uDom('#buttonApply').toggleClass('enabled', false); uDom('#buttonApply').toggleClass('enabled', false);
}; };
@ -368,16 +409,28 @@ var buttonApplyHandler = function() {
var buttonUpdateHandler = function() { var buttonUpdateHandler = function() {
if ( needUpdate ) { if ( needUpdate ) {
reloadAll(true); renderBusyOverlay(true);
var onSelectionDone = function() {
messager.send({ what: 'forceUpdateAssets' });
};
selectFilterLists(onSelectionDone);
cacheWasPurged = false;
} }
uDom('#buttonPurgeAll').toggleClass('enabled', false);
}; };
/******************************************************************************/ /******************************************************************************/
var buttonPurgeAllHandler = function() { var buttonPurgeAllHandler = function() {
var onCompleted = function() { var onCompleted = function() {
renderBlacklists(); cacheWasPurged = true;
renderFilterLists();
}; };
messager.send({ what: 'purgeAllCaches' }, onCompleted); messager.send({ what: 'purgeAllCaches' }, onCompleted);
}; };
@ -395,7 +448,7 @@ var autoUpdateCheckboxChanged = function() {
var cosmeticSwitchChanged = function() { var cosmeticSwitchChanged = function() {
listDetails.cosmetic = this.checked; listDetails.cosmetic = this.checked;
updateWidgets(); renderWidgets();
}; };
/******************************************************************************/ /******************************************************************************/
@ -426,7 +479,7 @@ var externalListsApplyHandler = function() {
name: 'externalLists', name: 'externalLists',
value: externalLists value: externalLists
}); });
renderBlacklists(); renderFilterLists();
uDom('#externalListsApply').prop('disabled', true); uDom('#externalListsApply').prop('disabled', true);
}; };
@ -444,7 +497,7 @@ uDom.onLoad(function() {
uDom('#externalLists').on('input', externalListsChangeHandler); uDom('#externalLists').on('input', externalListsChangeHandler);
uDom('#externalListsApply').on('click', externalListsApplyHandler); uDom('#externalListsApply').on('click', externalListsApplyHandler);
renderBlacklists(); renderFilterLists();
renderExternalLists(); renderExternalLists();
}); });

View file

@ -53,7 +53,6 @@ var oneDay = 24 * oneHour;
/******************************************************************************/ /******************************************************************************/
var projectRepositoryRoot = µBlock.projectServerRoot; var projectRepositoryRoot = µBlock.projectServerRoot;
var thirdpartiesRepositoryRoot = 'https://raw.githubusercontent.com/gorhill/uAssets/master/src';
var nullFunc = function() {}; var nullFunc = function() {};
var reIsExternalPath = /^[a-z]+:\/\//; var reIsExternalPath = /^[a-z]+:\/\//;
var reIsUserPath = /^assets\/user\//; var reIsUserPath = /^assets\/user\//;
@ -1117,7 +1116,10 @@ return exports;
var µb = µBlock; var µb = µBlock;
var updateDaemonTimerPeriod = 11 * 60 * 1000; // 11 minutes var updateDaemonTimer = null;
var autoUpdateDaemonTimerPeriod = 11 * 60 * 1000; // 11 minutes
var manualUpdateDaemonTimerPeriod = 5 * 1000; // 5 seconds
var updateCycleFirstPeriod = 7 * 60 * 1000; // 7 minutes var updateCycleFirstPeriod = 7 * 60 * 1000; // 7 minutes
var updateCycleNextPeriod = 11 * 60 * 60 * 1000; // 11 hours var updateCycleNextPeriod = 11 * 60 * 60 * 1000; // 11 hours
var updateCycleTime = 0; var updateCycleTime = 0;
@ -1132,28 +1134,44 @@ var onStartListener = null;
var onCompletedListener = null; var onCompletedListener = null;
var onAssetUpdatedListener = null; var onAssetUpdatedListener = null;
var exports = {}; var exports = {
manualUpdate: false,
manualUpdateProgress: {
value: 0,
text: null
}
};
/******************************************************************************/ /******************************************************************************/
var onAssetUpdated = function(details) { var onAssetUpdated = function(details) {
// Resource fetched, we can safely restart the daemon.
scheduleUpdateDaemon();
var path = details.path; var path = details.path;
if ( details.error ) { if ( details.error ) {
//console.debug('µBlock.assetUpdater/onAssetUpdated: "%s" failed', path); //console.debug('µBlock.assetUpdater/onAssetUpdated: "%s" failed', path);
return; return;
} }
//console.debug('µBlock.assetUpdater/onAssetUpdated: "%s"', path); //console.debug('µBlock.assetUpdater/onAssetUpdated: "%s"', path);
updated[path] = true; updated[path] = true;
updatedCount += 1; updatedCount += 1;
if ( typeof onAssetUpdatedListener === 'function' ) { if ( typeof onAssetUpdatedListener === 'function' ) {
onAssetUpdatedListener(details); onAssetUpdatedListener(details);
} }
manualUpdateNotify(false, updatedCount / (updatedCount + toUpdateCount + 1));
}; };
/******************************************************************************/ /******************************************************************************/
var updateOne = function() { var updateOne = function() {
var metaEntry; var metaEntry;
var updatingCount = 0;
var updatingText = null;
for ( var path in toUpdate ) { for ( var path in toUpdate ) {
if ( toUpdate.hasOwnProperty(path) === false ) { if ( toUpdate.hasOwnProperty(path) === false ) {
continue; continue;
@ -1170,10 +1188,25 @@ var updateOne = function() {
if ( !metaEntry.cacheObsolete && !metaEntry.repoObsolete ) { if ( !metaEntry.cacheObsolete && !metaEntry.repoObsolete ) {
continue; continue;
} }
// Will restart the update daemon once the resource is received: the
// fetching of a resource may take some time, possibly beyond the
// next scheduled daemon cycle, so this ensure the daemon won't do
// anything else before the resource is fetched (or times out).
suspendUpdateDaemon();
//console.debug('µBlock.assetUpdater/updateOne: assets.get("%s")', path); //console.debug('µBlock.assetUpdater/updateOne: assets.get("%s")', path);
µb.assets.get(path, onAssetUpdated); µb.assets.get(path, onAssetUpdated);
updatingCount = 1;
updatingText = metaEntry.homeURL || path;
break; break;
} }
manualUpdateNotify(
false,
(updatedCount + updatingCount/2) / (updatedCount + toUpdateCount + updatingCount + 1),
updatingText
);
}; };
/******************************************************************************/ /******************************************************************************/
@ -1186,9 +1219,10 @@ var onMetadataReady = function(response) {
/******************************************************************************/ /******************************************************************************/
var updateDaemon = function() { var updateDaemon = function() {
setTimeout(updateDaemon, updateDaemonTimerPeriod); updateDaemonTimer = null;
scheduleUpdateDaemon();
µb.assets.autoUpdate = µb.userSettings.autoUpdate; µb.assets.autoUpdate = µb.userSettings.autoUpdate || exports.manualUpdate;
if ( µb.assets.autoUpdate !== true ) { if ( µb.assets.autoUpdate !== true ) {
return; return;
@ -1217,6 +1251,9 @@ var updateDaemon = function() {
} }
// Nothing left to update // Nothing left to update
// In case of manual update, fire progress notifications
manualUpdateNotify(true, 1, '');
// If anything was updated, notify listener // If anything was updated, notify listener
if ( updatedCount !== 0 ) { if ( updatedCount !== 0 ) {
if ( typeof onCompletedListener === 'function' ) { if ( typeof onCompletedListener === 'function' ) {
@ -1236,7 +1273,26 @@ var updateDaemon = function() {
} }
}; };
setTimeout(updateDaemon, updateDaemonTimerPeriod); /******************************************************************************/
var scheduleUpdateDaemon = function() {
if ( updateDaemonTimer !== null ) {
clearTimeout(updateDaemonTimer);
}
updateDaemonTimer = setTimeout(
updateDaemon,
exports.manualUpdate ? manualUpdateDaemonTimerPeriod : autoUpdateDaemonTimerPeriod
);
};
var suspendUpdateDaemon = function() {
if ( updateDaemonTimer !== null ) {
clearTimeout(updateDaemonTimer);
updateDaemonTimer = null;
}
};
scheduleUpdateDaemon();
/******************************************************************************/ /******************************************************************************/
@ -1251,6 +1307,67 @@ var reset = function() {
/******************************************************************************/ /******************************************************************************/
// Manual update: just a matter of forcing the update daemon to work on a
// tighter schedule.
exports.force = function() {
if ( exports.manualUpdate ) {
return;
}
if ( updateDaemonTimer !== null ) {
clearTimeout(updateDaemonTimer);
}
reset();
if ( typeof onStartListener === 'function' ) {
onStartListener();
}
// This must be done here
exports.manualUpdate = true;
if ( toUpdateCount === 0 ) {
updateCycleTime = Date.now() + updateCycleNextPeriod;
scheduleUpdateDaemon();
manualUpdateNotify(true, 1);
return;
}
scheduleUpdateDaemon();
manualUpdateNotify(false, 0);
};
/******************************************************************************/
var manualUpdateNotify = function(done, value, text) {
if ( exports.manualUpdate === false ) {
return;
}
exports.manualUpdate = !done;
exports.manualUpdateProgress.value = value || 0;
if ( typeof text === 'string' ) {
exports.manualUpdateProgress.text = text;
}
vAPI.messaging.broadcast({
what: 'forceUpdateAssetsProgress',
done: !exports.manualUpdate,
progress: exports.manualUpdateProgress,
updatedCount: updatedCount
});
// When manually updating, whatever launched the manual update is
// responsible to launch a reload of the filter lists.
if ( exports.manualUpdate !== true ) {
reset();
}
};
/******************************************************************************/
exports.onStart = { exports.onStart = {
addEventListener: function(callback) { addEventListener: function(callback) {
onStartListener = callback || null; onStartListener = callback || null;

View file

@ -42,6 +42,10 @@ var onMessage = function(request, sender, callback) {
µb.assets.get(request.url, callback); µb.assets.get(request.url, callback);
return; return;
case 'reloadAllFilters':
µb.reloadAllFilters(callback);
return;
default: default:
break; break;
} }
@ -55,6 +59,10 @@ var onMessage = function(request, sender, callback) {
µb.contextMenuClientY = request.clientY; µb.contextMenuClientY = request.clientY;
break; break;
case 'forceUpdateAssets':
µb.assetUpdater.force();
break;
case 'getAppData': case 'getAppData':
response = {name: vAPI.app.name, version: vAPI.app.version}; response = {name: vAPI.app.name, version: vAPI.app.version};
break; break;
@ -67,16 +75,16 @@ var onMessage = function(request, sender, callback) {
vAPI.tabs.open(request.details); vAPI.tabs.open(request.details);
break; break;
case 'reloadAllFilters':
µb.reloadFilterLists(request.switches, request.update);
break;
case 'reloadTab': case 'reloadTab':
if ( vAPI.isNoTabId(request.tabId) === false ) { if ( vAPI.isNoTabId(request.tabId) === false ) {
vAPI.tabs.reload(request.tabId); vAPI.tabs.reload(request.tabId);
} }
break; break;
case 'selectFilterLists':
µb.selectFilterLists(request.switches);
break;
case 'userSettings': case 'userSettings':
response = µb.changeUserSettings(request.name, request.value); response = µb.changeUserSettings(request.name, request.value);
break; break;
@ -634,17 +642,20 @@ var prepEntries = function(entries) {
var getLists = function(callback) { var getLists = function(callback) {
var r = { var r = {
available: null,
current: µb.remoteBlacklists,
cosmetic: µb.userSettings.parseAllABPHideFilters,
netFilterCount: µb.staticNetFilteringEngine.getFilterCount(),
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
autoUpdate: µb.userSettings.autoUpdate, autoUpdate: µb.userSettings.autoUpdate,
userFiltersPath: µb.userFiltersPath, available: null,
cache: null cache: null,
cosmetic: µb.userSettings.parseAllABPHideFilters,
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
current: µb.remoteBlacklists,
manualUpdate: false,
netFilterCount: µb.staticNetFilteringEngine.getFilterCount(),
userFiltersPath: µb.userFiltersPath
}; };
var onMetadataReady = function(entries) { var onMetadataReady = function(entries) {
r.cache = entries; r.cache = entries;
r.manualUpdate = µb.assetUpdater.manualUpdate;
r.manualUpdateProgress = µb.assetUpdater.manualUpdateProgress;
prepEntries(r.cache); prepEntries(r.cache);
callback(r); callback(r);
}; };

View file

@ -27,6 +27,8 @@
(function() { (function() {
'use strict';
//quickProfiler.start('start.js'); //quickProfiler.start('start.js');
/******************************************************************************/ /******************************************************************************/
@ -126,6 +128,7 @@ var onUserSettingsReady = function(fetched) {
// time. // time.
µb.assets.allowRemoteFetch = false; µb.assets.allowRemoteFetch = false;
µb.assets.autoUpdate = userSettings.autoUpdate; µb.assets.autoUpdate = userSettings.autoUpdate;
µb.assets.autoUpdateDelay = µb.updateAssetsEvery;
// https://github.com/gorhill/uBlock/issues/540 // https://github.com/gorhill/uBlock/issues/540
// Disabling local mirroring for the time being // Disabling local mirroring for the time being

View file

@ -182,8 +182,15 @@
if ( storedEntry.entryUsedCount !== undefined ) { if ( storedEntry.entryUsedCount !== undefined ) {
availableEntry.entryUsedCount = storedEntry.entryUsedCount; availableEntry.entryUsedCount = storedEntry.entryUsedCount;
} }
// This may happen if the list name was pulled from the list content // This may happen if the list name was pulled from the list
if ( availableEntry.title === '' && storedEntry.title !== '' ) { // content.
// https://github.com/gorhill/uBlock/issues/982
// There is no guarantee the title was successfully extracted from
// the list content.
if ( availableEntry.title === '' &&
typeof storedEntry.title === 'string' &&
storedEntry.title !== ''
) {
availableEntry.title = storedEntry.title; availableEntry.title = storedEntry.title;
} }
} }
@ -514,78 +521,47 @@
// `switches` contains the filter lists for which the switch must be revisited. // `switches` contains the filter lists for which the switch must be revisited.
µBlock.reloadFilterLists = function(switches, update) { µBlock.selectFilterLists = function(switches) {
var µb = this; switches = switches || {};
var onFilterListsReady = function() { // Only the lists referenced by the switches are touched.
µb.loadUpdatableAssets({ update: update, psl: update }); var filterLists = this.remoteBlacklists;
}; var entry, state, location;
var i = switches.length;
var onPurgeDone = function() { while ( i-- ) {
// Toggle switches, if any entry = switches[i];
if ( switches === undefined ) { state = entry.off === true;
onFilterListsReady(); location = entry.location;
return; if ( filterLists.hasOwnProperty(location) === false ) {
} if ( state !== true ) {
filterLists[location] = { off: state };
// Only the lists referenced by the switches are touched.
var filterLists = µb.remoteBlacklists;
var entry, state, location;
var i = switches.length;
while ( i-- ) {
entry = switches[i];
state = entry.off === true;
location = entry.location;
if ( filterLists.hasOwnProperty(location) === false ) {
if ( state !== true ) {
filterLists[location] = { off: state };
}
continue;
} }
if ( filterLists[location].off === state ) { continue;
continue;
}
filterLists[location].off = state;
} }
if ( filterLists[location].off === state ) {
vAPI.storage.set({ 'remoteBlacklists': filterLists }, onFilterListsReady); continue;
}; }
filterLists[location].off = state;
// If we must update, we need to purge the compiled versions of
// obsolete assets.
if ( update !== true ) {
onPurgeDone();
return;
} }
var onMetadataReady = function(metadata) { vAPI.storage.set({ 'remoteBlacklists': filterLists });
var filterLists = µb.remoteBlacklists; };
var entry;
// Purge obsolete filter lists /******************************************************************************/
for ( var path in filterLists ) {
if ( filterLists.hasOwnProperty(path) === false ) { // Plain reload of all filters.
continue;
} µBlock.reloadAllFilters = function() {
if ( metadata.hasOwnProperty(path) === false ) { var µb = this;
continue;
} // We are just reloading the filter lists: we do not want assets to update.
entry = metadata[path]; this.assets.autoUpdate = false;
if ( entry.repoObsolete !== true && entry.cacheObsolete !== true ) {
continue; var onFiltersReady = function() {
} µb.assets.autoUpdate = µb.userSettings.autoUpdate;
µb.purgeCompiledFilterList(path);
}
// Purge obsolete PSL
if ( metadata.hasOwnProperty(µb.pslPath) ) {
if ( metadata[µb.pslPath].repoObsolete === true ) {
µb.assets.purge('cache://compiled-publicsuffixlist');
}
}
onPurgeDone();
}; };
this.assets.metadata(onMetadataReady); this.loadFilterLists(onFiltersReady);
}; };
/******************************************************************************/ /******************************************************************************/
@ -623,36 +599,6 @@
/******************************************************************************/ /******************************************************************************/
// Load updatable assets
µBlock.loadUpdatableAssets = function(details) {
var µb = this;
details = details || {};
var update = details.update !== false;
this.assets.autoUpdate = update || this.userSettings.autoUpdate;
this.assets.autoUpdateDelay = this.updateAssetsEvery;
var onFiltersReady = function() {
if ( update ) {
µb.assetUpdater.restart();
}
};
var onPSLReady = function() {
µb.loadFilterLists(onFiltersReady);
};
if ( details.psl !== false ) {
this.loadPublicSuffixList(onPSLReady);
} else {
this.loadFilterLists(onFiltersReady);
}
};
/******************************************************************************/
µBlock.toSelfie = function() { µBlock.toSelfie = function() {
var selfie = { var selfie = {
magic: this.systemSettings.selfieMagic, magic: this.systemSettings.selfieMagic,

View file

@ -84,12 +84,15 @@ var onAbpLinkClicked = function(ev) {
ev.stopPropagation(); ev.stopPropagation();
ev.preventDefault(); ev.preventDefault();
var onListsSelectionDone = function() {
messager.send({ what: 'reloadAllFilters' });
};
var onExternalListsSaved = function() { var onExternalListsSaved = function() {
messager.send({ messager.send({
what: 'reloadAllFilters', what: 'selectFilterLists',
switches: [ { location: location, off: false } ], switches: [ { location: location, off: false } ]
update: false }, onListsSelectionDone);
});
}; };
var onSubscriberDataReady = function(details) { var onSubscriberDataReady = function(details) {