diff --git a/3p-filters.html b/3p-filters.html index ff9cce186..c2706f548 100644 --- a/3p-filters.html +++ b/3p-filters.html @@ -36,11 +36,17 @@ ul > li > ul > li { .dim { color: #888; } -.userUbiquitousHosts { - font-size: smaller; - width: 36em; - height: 16em; - white-space: nowrap; +button.purge { + margin: 0; + border: 1px solid #ccc; + padding: 1px 2px; + color: #444; + background-color: #eee; + font-size: 11px; + opacity: 0.6; + } +button.purge:hover { + opacity: 1; } #externalLists { font-size: smaller; diff --git a/_locales/de/messages.json b/_locales/de/messages.json index efdf21235..c5339aea6 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -143,6 +143,10 @@ "message":"Anwenden", "description":"English: Apply" }, + "3pExternalListPurge":{ + "message":"purge cache", + "description":"English: purge cache" + }, "1pFormatHint":{ "message":"Eine Regel pro Zeile. Eine Regel kann ein einfacher Host-Name sein oder ein Adblock Plus-kompatibler Filter. Zeilen mit vorangestelltem ‘!’ werden ignoriert.", "description":"English: One filter per line. A filter can be a plain hostname, or an Adblock Plus-compatible filter. Lines prefixed with ‘!’ will be ignored." diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 543cd8dc7..1a71b908e 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -143,6 +143,10 @@ "message":"Apply", "description":"English: Apply" }, + "3pExternalListPurge":{ + "message":"purge cache", + "description":"English: purge cache" + }, "1pFormatHint":{ "message":"One filter per line. A filter can be a plain hostname, or an Adblock Plus-compatible filter. Lines prefixed with ‘!’ 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 ‘!’ will be ignored." diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index c7eefb10a..237e26060 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -143,6 +143,10 @@ "message":"Appliquer", "description":"English: Apply" }, + "3pExternalListPurge":{ + "message":"purge cache", + "description":"English: purge cache" + }, "1pFormatHint":{ "message":"Une règle par ligne. Une règle peut être un simple nom d'hôte, ou encore un filtre respectant la syntaxe des filtres Adblock Plus. Les lignes débutant par ‘!’ seront ignorées.", "description":"English: One filter per line. A filter can be a plain hostname, or an Adblock Plus-compatible filter. Lines prefixed with ‘!’ will be ignored." diff --git a/js/3p-filters.js b/js/3p-filters.js index defeac988..ac1876346 100644 --- a/js/3p-filters.js +++ b/js/3p-filters.js @@ -30,6 +30,7 @@ var userListName = chrome.i18n.getMessage('1pPageName'); var listDetails = {}; var externalLists = ''; +var cacheWasPurged = false; /******************************************************************************/ @@ -107,6 +108,7 @@ var renderBlacklists = function() { }; var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats'); + var purgeButtontext = chrome.i18n.getMessage('3pExternalListPurge'); var htmlFromBranch = function(groupKey, listKeys, lists) { var html = [ @@ -143,6 +145,15 @@ var renderBlacklists = function() { .replace('{{used}}', !list.off && !isNaN(+list.entryUsedCount) ? renderNumber(list.entryUsedCount) : '0') .replace('{{total}}', !isNaN(+list.entryCount) ? renderNumber(list.entryCount) : '?'); html.push(listEntry); + // https://github.com/gorhill/uBlock/issues/104 + if ( /^https?:\/\/.+/.test(listKey) && listDetails.cache[listKey] ) { + html.push( + ' ', + '' + ); + } } html.push(''); return html.join(''); @@ -217,6 +228,9 @@ var needToReload = function() { if ( listDetails.cosmetic !== getµb().userSettings.parseAllABPHideFilters ) { return true; } + if ( cacheWasPurged ) { + return true; + } var availableLists = listDetails.available; var currentLists = listDetails.current; var location, availableOff, currentOff; @@ -279,6 +293,20 @@ var onListLinkClicked = function(ev) { /******************************************************************************/ +var onPurgeClicked = function(ev) { + var button = uDom(this); + var href = button.parent().find('a').first().attr('href'); + if ( !href ) { + return; + } + messaging.tell({ what: 'purgeCache', path: href }); + button.remove(); + cacheWasPurged = true; + selectedBlacklistsChanged(); +}; + +/******************************************************************************/ + var blacklistsApplyHandler = function() { if ( !needToReload() ) { return; @@ -308,6 +336,7 @@ var blacklistsApplyHandler = function() { what: 'reloadAllFilters', switches: switches }); + cacheWasPurged = false; uDom('#blacklistsApply').prop('disabled', true); }; @@ -358,6 +387,7 @@ uDom.onLoad(function() { uDom('#blacklistsApply').on('click', blacklistsApplyHandler); uDom('#lists').on('change', '.listDetails > input', onListCheckboxChanged); uDom('#lists').on('click', '.listDetails > a:nth-of-type(1)', onListLinkClicked); + uDom('#lists').on('click', 'button.purge', onPurgeClicked); uDom('#externalLists').on('input', externalListsChangeHandler); uDom('#externalListsApply').on('click', externalListsApplyHandler); diff --git a/js/assets.js b/js/assets.js index 997cbfa2a..3f202d13c 100644 --- a/js/assets.js +++ b/js/assets.js @@ -95,6 +95,7 @@ var cachedAssetsManager = (function() { }; chrome.storage.local.get('cached_asset_entries', onLoaded); }; + exports.entries = getEntries; exports.load = function(path, cbSuccess, cbError) { cbSuccess = cbSuccess || nullFunc; @@ -625,6 +626,12 @@ var updateFromRemote = function(details, callback) { /******************************************************************************/ +var cacheEntries = function(callback) { + return cachedAssetsManager.entries(callback); +}; + +/******************************************************************************/ + // Flush cached assets if cache content is from an older version: the extension // always ships with the most up-to-date assets. @@ -640,7 +647,8 @@ return { 'getRepo': readRepoFile, 'purge': purgeCache, 'put': writeLocalFile, - 'update': updateFromRemote + 'update': updateFromRemote, + 'entries': cacheEntries }; /******************************************************************************/ diff --git a/js/messaging-handlers.js b/js/messaging-handlers.js index ef2313ad4..c7d02d2f5 100644 --- a/js/messaging-handlers.js +++ b/js/messaging-handlers.js @@ -235,14 +235,26 @@ var onMessage = function(request, sender, callback) { var getLists = function(callback) { var µb = µBlock; - var onReceived = function(lists) { - callback({ - available: lists, - current: µb.remoteBlacklists, - cosmetic: µb.userSettings.parseAllABPHideFilters - }); + var r = { + available: null, + current: µb.remoteBlacklists, + cosmetic: µb.userSettings.parseAllABPHideFilters, + cache: null }; - µb.getAvailableLists(onReceived); + var onEntries = function(entries) { + r.cache = entries; + if ( r.available ) { + callback(r); + } + }; + var onLists = function(lists) { + r.available = lists; + if ( r.cache ) { + callback(r); + } + }; + µb.getAvailableLists(onLists); + µb.assets.entries(onEntries); }; /******************************************************************************/ @@ -269,6 +281,10 @@ var onMessage = function(request, sender, callback) { var response; switch ( request.what ) { + case 'purgeCache': + µb.assets.purge(request.path); + break; + default: return µb.messaging.defaultHandler(request, sender, callback); }