This commit is contained in:
gorhill 2015-03-08 17:54:08 -04:00
parent 8341fb2193
commit 3544989e69
3 changed files with 82 additions and 98 deletions

View file

@ -20,8 +20,7 @@
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div> <div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
<li><p id="listsOfBlockedHostsPrompt"></p> <li><p id="listsOfBlockedHostsPrompt"></p>
</ul> </ul>
<ul id="lists"> <ul id="lists"></ul>
</ul>
<div id="externalListsDiv"> <div id="externalListsDiv">
<p data-i18n="3pExternalListsHint" style="margin: 0 0 0.25em 0; font-size: 13px;"></p> <p data-i18n="3pExternalListsHint" style="margin: 0 0 0.25em 0; font-size: 13px;"></p>
@ -31,6 +30,23 @@
<div id="busyOverlay"></div> <div id="busyOverlay"></div>
<div id="templates" style="display: none;">
<ul>
<li class="groupEntry"><span></span>
<ul></ul>
</li>
<li class="listEntry">
<input type="checkbox">
<a type="text/plain" target="_blank" href=""></a>
<a href="" style="display: none;" target="_blank"></a>: <!--
--><span class="dim"></span><!--
--><span class="status new" style="display: none;" data-i18n="3pExternalListNew"></span><!--
--><span class="status obsolete" style="display: none;" data-i18n="3pExternalListObsolete"></span><!--
--><span class="status purge" style="display: none;" data-i18n="3pExternalListPurge"></span>
</li>
</ul>
</div>
<script src="js/vapi-common.js"></script> <script src="js/vapi-common.js"></script>
<script src="js/vapi-client.js"></script> <script src="js/vapi-client.js"></script>
<script src="js/udom.js"></script> <script src="js/udom.js"></script>

View file

@ -20,26 +20,28 @@ body[dir=rtl] #lists {
#lists > li { #lists > li {
margin: 0.5em 0 0 0; margin: 0.5em 0 0 0;
padding: 0; padding: 0;
font-size: 15px;
list-style-type: none; list-style-type: none;
} }
#lists > li > span {
font-size: 15px;
}
#lists > li > ul { #lists > li > ul {
margin: 0.25em 0 0 0; margin: 0.25em 0 0 0;
} }
li.listDetails { li.listEntry {
font-size: 14px; font-size: 14px;
margin: 0 auto 0 auto; margin: 0 auto 0 auto;
margin-left: 1em; margin-left: 1em;
margin-right: 0em; margin-right: 0em;
} }
body[dir=rtl] li.listDetails { body[dir=rtl] li.listEntry {
margin-left: 0em; margin-left: 0em;
margin-right: 1em; margin-right: 1em;
} }
li.listDetails > * { li.listEntry > * {
unicode-bidi: embed; unicode-bidi: embed;
} }
li.listDetails > a:nth-of-type(2) { li.listEntry > a:nth-of-type(2) {
font-size: 13px; font-size: 13px;
opacity: 0.5; opacity: 0.5;
} }
@ -89,11 +91,12 @@ body[dir=rtl] #buttonApply {
display: none; display: none;
} }
span.status { span.status {
margin: 0; margin: 0 0 0 1em;
border: 1px solid transparent; border: 1px solid transparent;
padding: 1px 2px; padding: 1px 2px;
display: inline-block; display: inline-block;
font-size: 11px; font-size: smaller;
line-height: 1;
opacity: 0.7; opacity: 0.7;
} }
span.purge { span.purge {

View file

@ -67,6 +67,10 @@ var renderNumber = function(value) {
var renderBlacklists = function() { var renderBlacklists = function() {
uDom('body').toggleClass('busy', true); uDom('body').toggleClass('busy', true);
var listGroupTemplate = uDom('#templates .groupEntry');
var listEntryTemplate = uDom('#templates .listEntry');
var listStatsTemplate = vAPI.i18n('3pListsOfBlockedHostsPerListStats');
// Assemble a pretty blacklist name if possible // Assemble a pretty blacklist name if possible
var listNameFromListKey = function(listKey) { var listNameFromListKey = function(listKey) {
if ( listKey === listDetails.userFiltersPath ) { if ( listKey === listDetails.userFiltersPath ) {
@ -80,98 +84,71 @@ var renderBlacklists = function() {
return listTitle; return listTitle;
}; };
// Assemble a pretty blacklist name if possible var liFromListEntry = function(listKey) {
var htmlFromHomeURL = function(entry) { var elem, text;
if ( !entry.homeDomain ) { var entry = listDetails.available[listKey];
return ''; var li = listEntryTemplate.clone();
if ( entry.off !== true ) {
li.descendants('input').attr('checked', '');
} }
return [
' <a href="http://',
entry.homeHostname,
'" target="_blank">(',
entry.homeDomain,
')</a>'
].join('');
};
var purgeButtontext = vAPI.i18n('3pExternalListPurge'); elem = li.descendants('a:nth-of-type(1)');
var updateButtontext = vAPI.i18n('3pExternalListNew'); elem.attr('href', encodeURI(listKey));
var obsoleteButtontext = vAPI.i18n('3pExternalListObsolete'); elem.text(listNameFromListKey(listKey) + '\u200E');
var liTemplate = [
'<li class="listDetails">', elem = li.descendants('a:nth-of-type(2)');
'<input type="checkbox" {{checked}}>', if ( entry.homeDomain ) {
' ', elem.attr('href', 'http://' + encodeURI(entry.homeHostname));
'<a data-href="{{URL}}" type="text/plain">', elem.text('(' + entry.homeDomain + ')');
'{{name}}', elem.css('display', '');
'\u200E</a>', }
'{{homeURL}}',
': ', elem = li.descendants('span:nth-of-type(1)');
'<span class="dim">', text = listStatsTemplate
vAPI.i18n('3pListsOfBlockedHostsPerListStats'), .replace('{{used}}', renderNumber(!entry.off && !isNaN(+entry.entryUsedCount) ? entry.entryUsedCount : 0))
'</span>' .replace('{{total}}', !isNaN(+entry.entryCount) ? renderNumber(entry.entryCount) : '?');
].join(''); elem.text(text);
var htmlFromLeaf = function(listKey) {
var html = [];
var list = listDetails.available[listKey];
var li = liTemplate
.replace('{{checked}}', list.off ? '' : 'checked')
.replace('{{URL}}', encodeURI(listKey))
.replace('{{name}}', listNameFromListKey(listKey))
.replace('{{homeURL}}', htmlFromHomeURL(list))
.replace('{{used}}', !list.off && !isNaN(+list.entryUsedCount) ? renderNumber(list.entryUsedCount) : '0')
.replace('{{total}}', !isNaN(+list.entryCount) ? renderNumber(list.entryCount) : '?');
html.push(li);
// https://github.com/gorhill/uBlock/issues/104 // https://github.com/gorhill/uBlock/issues/104
var asset = listDetails.cache[listKey]; var asset = listDetails.cache[listKey] || {};
if ( asset === undefined ) {
return html.join('\n');
}
// Update status // Update status
if ( list.off !== true ) { if ( entry.off !== true ) {
var obsolete = asset.repoObsolete || if ( asset.repoObsolete ) {
asset.cacheObsolete || li.descendants('span.status.new').css('display', '');
asset.cached !== true && re3rdPartyExternalAsset.test(listKey); needUpdate = true;
if ( obsolete ) { } else if ( asset.cacheObsolete ) {
html.push( li.descendants('span.status.obsolete').css('display', '');
'&ensp;', needUpdate = true;
'<span class="status obsolete">', } else if ( entry.external && !asset.cached ) {
asset.repoObsolete ? updateButtontext : obsoleteButtontext, li.descendants('span.status.obsolete').css('display', '');
'</span>'
);
needUpdate = true; needUpdate = true;
} }
} }
// In cache // In cache
if ( asset.cached ) { if ( asset.cached ) {
html.push( li.descendants('span.status.purge').css('display', '');
'&ensp;',
'<span class="status purge">',
purgeButtontext,
'</span>'
);
hasCachedContent = true; hasCachedContent = true;
} }
return html.join('\n'); return li;
}; };
var htmlFromBranch = function(groupKey, listKeys) { var liFromListGroup = function(groupKey, listKeys) {
var html = [ var liGroup = listGroupTemplate.clone();
'<li>', liGroup.descendants('span').text(vAPI.i18n('3pGroup' + groupKey.charAt(0).toUpperCase() + groupKey.slice(1)));
vAPI.i18n('3pGroup' + groupKey.charAt(0).toUpperCase() + groupKey.slice(1)), var ulGroup = liGroup.descendants('ul');
'<ul>'
];
if ( !listKeys ) { if ( !listKeys ) {
return html.join(''); return liGroup;
} }
listKeys.sort(function(a, b) { listKeys.sort(function(a, b) {
return (listDetails.available[a].title || "").localeCompare(listDetails.available[b].title || ""); return (listDetails.available[a].title || "").localeCompare(listDetails.available[b].title || "");
}); });
for ( var i = 0; i < listKeys.length; i++ ) { for ( var i = 0; i < listKeys.length; i++ ) {
html.push(htmlFromLeaf(listKeys[i])); ulGroup.append(liFromListEntry(listKeys[i]));
} }
html.push('</ul>'); return liGroup;
return html.join('');
}; };
// https://www.youtube.com/watch?v=unCVi4hYRlY#t=30m18s // https://www.youtube.com/watch?v=unCVi4hYRlY#t=30m18s
@ -201,7 +178,7 @@ var renderBlacklists = function() {
hasCachedContent = false; hasCachedContent = false;
// Visually split the filter lists in purpose-based groups // Visually split the filter lists in purpose-based groups
var html = []; var ulLists = uDom('#lists').empty();
var groups = groupsFromLists(details.available); var groups = groupsFromLists(details.available);
var groupKey, i; var groupKey, i;
var groupKeys = [ var groupKeys = [
@ -216,15 +193,14 @@ var renderBlacklists = function() {
]; ];
for ( i = 0; i < groupKeys.length; i++ ) { for ( i = 0; i < groupKeys.length; i++ ) {
groupKey = groupKeys[i]; groupKey = groupKeys[i];
html.push(htmlFromBranch(groupKey, groups[groupKey])); ulLists.append(liFromListGroup(groupKey, groups[groupKey]));
delete groups[groupKey]; delete groups[groupKey];
} }
// For all groups not covered above (if any left) // For all groups not covered above (if any left)
groupKeys = Object.keys(groups); groupKeys = Object.keys(groups);
for ( i = 0; i < groupKeys.length; i++ ) { for ( i = 0; i < groupKeys.length; i++ ) {
groupKey = groupKeys[i]; groupKey = groupKeys[i];
html.push(htmlFromBranch(groupKey, groups[groupKey])); ulLists.append(liFromListGroup(groupKey, groups[groupKey]));
delete groups[groupKey];
} }
uDom('#listsOfBlockedHostsPrompt').text( uDom('#listsOfBlockedHostsPrompt').text(
@ -234,17 +210,6 @@ 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);
uDom('#lists').html(html.join(''));
uDom('a').attr('target', '_blank');
// Firefox: sanitizer drops those `href` attributes that point to local URLs
var lis = uDom('a[data-href]');
var a;
i = lis.length;
while ( i-- ) {
a = lis.subset(i, 1);
a.attr('href', a.attr('data-href'));
}
updateWidgets(); updateWidgets();
}; };
@ -370,7 +335,7 @@ var reloadAll = function(update) {
}); });
// Reload blacklists // Reload blacklists
var switches = []; var switches = [];
var lis = uDom('#lists .listDetails'); var lis = uDom('#lists .listEntry');
var i = lis.length; var i = lis.length;
var path; var path;
while ( i-- ) { while ( i-- ) {
@ -472,8 +437,8 @@ uDom.onLoad(function() {
uDom('#buttonApply').on('click', buttonApplyHandler); uDom('#buttonApply').on('click', buttonApplyHandler);
uDom('#buttonUpdate').on('click', buttonUpdateHandler); uDom('#buttonUpdate').on('click', buttonUpdateHandler);
uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler); uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler);
uDom('#lists').on('change', '.listDetails > input', onListCheckboxChanged); uDom('#lists').on('change', '.listEntry > input', onListCheckboxChanged);
uDom('#lists').on('click', '.listDetails > a:nth-of-type(1)', onListLinkClicked); uDom('#lists').on('click', '.listEntry > a:nth-of-type(1)', onListLinkClicked);
uDom('#lists').on('click', 'span.purge', onPurgeClicked); uDom('#lists').on('click', 'span.purge', onPurgeClicked);
uDom('#externalLists').on('input', externalListsChangeHandler); uDom('#externalLists').on('input', externalListsChangeHandler);
uDom('#externalListsApply').on('click', externalListsApplyHandler); uDom('#externalListsApply').on('click', externalListsApplyHandler);