mirror of https://github.com/gorhill/uBlock.git
code review
This commit is contained in:
parent
d4789499ac
commit
b2d78bcc16
|
@ -10,15 +10,15 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<button id="buttonApply" class="reloadAll" 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>
|
||||||
<button class="reloadAll" id="buttonUpdate" data-i18n="3pUpdateNow"></button>
|
<button class="custom reloadAll disabled" id="buttonUpdate" data-i18n="3pUpdateNow"></button>
|
||||||
<button id="buttonPurgeAll" 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>
|
||||||
<button class="whatisthis"></button>
|
<button class="whatisthis"></button>
|
||||||
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
|
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
|
||||||
<li style="margin-top:0.75em"><p id="listsOfBlockedHostsPrompt"></p>
|
<li><p id="listsOfBlockedHostsPrompt"></p>
|
||||||
</ul>
|
</ul>
|
||||||
<ul id="lists">
|
<ul id="lists">
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<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="loadingOverlay"></div>
|
<div id="busyOverlay"></div>
|
||||||
|
|
||||||
<script src="js/udom.js"></script>
|
<script src="js/udom.js"></script>
|
||||||
<script src="js/i18n.js"></script>
|
<script src="js/i18n.js"></script>
|
||||||
|
|
|
@ -2,6 +2,12 @@ ul {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
ul#options {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
ul#options li {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
ul#lists {
|
ul#lists {
|
||||||
margin: 0.5em 0 0 0;
|
margin: 0.5em 0 0 0;
|
||||||
padding-__MSG_@@bidi_end_edge__: 0em;
|
padding-__MSG_@@bidi_end_edge__: 0em;
|
||||||
|
@ -33,40 +39,41 @@ li.listDetails > a:nth-of-type(2) {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
/* I designed the button with: http://charliepark.org/bootstrap_buttons/ */
|
/* I designed the button with: http://charliepark.org/bootstrap_buttons/ */
|
||||||
button {
|
button.custom {
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 3px;
|
|
||||||
border-color: #dddddd #dddddd hsl(36, 0%, 85%);
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background-color: hsl(36, 0%, 72%);
|
border: 1px solid transparent;
|
||||||
background-repeat: repeat-x;
|
|
||||||
background-image: linear-gradient(#f2f2f2, #dddddd);
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
button.enabled {
|
|
||||||
border-color: #80b3ff #80b3ff hsl(216, 100%, 75%);
|
border-color: #80b3ff #80b3ff hsl(216, 100%, 75%);
|
||||||
|
border-radius: 3px;
|
||||||
background-color: hsl(216, 100%, 75%);
|
background-color: hsl(216, 100%, 75%);
|
||||||
background-image: linear-gradient(#a8cbff, #80b3ff);
|
background-image: linear-gradient(#a8cbff, #80b3ff);
|
||||||
|
background-repeat: repeat-x;
|
||||||
color: #222;
|
color: #222;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
button.reloadAll.enabled {
|
button.custom.disabled {
|
||||||
|
border-color: #dddddd #dddddd hsl(36, 0%, 85%);
|
||||||
|
background-color: hsl(36, 0%, 72%);
|
||||||
|
background-image: linear-gradient(#f2f2f2, #dddddd);
|
||||||
|
color: #aaa;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
button.custom:hover {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
button.custom.reloadAll:not(.disabled) {
|
||||||
border-color: #ffcc7f #ffcc7f hsl(36, 100%, 73%);
|
border-color: #ffcc7f #ffcc7f hsl(36, 100%, 73%);
|
||||||
background-color: hsl(36, 100%, 75%);
|
background-color: hsl(36, 100%, 75%);
|
||||||
background-image: linear-gradient(#ffdca8, #ffcc7f);
|
background-image: linear-gradient(#ffdca8, #ffcc7f);
|
||||||
}
|
}
|
||||||
button.enabled:hover {
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
#buttonApply {
|
#buttonApply {
|
||||||
display: none;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
display: initial;
|
||||||
top: 1em;
|
top: 1em;
|
||||||
__MSG_@@bidi_end_edge__: 1em;
|
__MSG_@@bidi_end_edge__: 1em;
|
||||||
}
|
}
|
||||||
#buttonApply.enabled {
|
#buttonApply.disabled {
|
||||||
display: initial;
|
display: none;
|
||||||
}
|
}
|
||||||
span.status {
|
span.status {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -100,7 +107,7 @@ span.obsolete {
|
||||||
height: 8em;
|
height: 8em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
body #loadingOverlay {
|
body #busyOverlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -112,6 +119,6 @@ body #loadingOverlay {
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
body.loading #loadingOverlay {
|
body.busy #busyOverlay {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
147
js/3p-filters.js
147
js/3p-filters.js
|
@ -35,8 +35,8 @@ var cacheWasPurged = false;
|
||||||
var needUpdate = false;
|
var needUpdate = false;
|
||||||
var hasCachedContent = false;
|
var hasCachedContent = false;
|
||||||
|
|
||||||
var reExternalAsset = /^https?:\/\/[a-z0-9]+/;
|
var re3rdPartyExternalAsset = /^https?:\/\/[a-z0-9]+/;
|
||||||
var reRepo3rdPartyAsset = /^assets\/thirdparties\/([^\/]+)/;
|
var re3rdPartyRepoAsset = /^assets\/thirdparties\/([^\/]+)/;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ messaging.start('3p-filters.js');
|
||||||
var onMessage = function(msg) {
|
var onMessage = function(msg) {
|
||||||
switch ( msg.what ) {
|
switch ( msg.what ) {
|
||||||
case 'loadUbiquitousBlacklistCompleted':
|
case 'loadUbiquitousBlacklistCompleted':
|
||||||
uDom('body').toggleClass('loading', false);
|
|
||||||
renderBlacklists();
|
renderBlacklists();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -73,6 +72,8 @@ var renderNumber = function(value) {
|
||||||
// TODO: get rid of background page dependencies
|
// TODO: get rid of background page dependencies
|
||||||
|
|
||||||
var renderBlacklists = function() {
|
var renderBlacklists = function() {
|
||||||
|
uDom('body').toggleClass('busy', true);
|
||||||
|
|
||||||
var µb = getµb();
|
var µb = getµb();
|
||||||
|
|
||||||
// Assemble a pretty blacklist name if possible
|
// Assemble a pretty blacklist name if possible
|
||||||
|
@ -91,7 +92,7 @@ var renderBlacklists = function() {
|
||||||
if ( blacklistHref.indexOf('assets/thirdparties/') !== 0 ) {
|
if ( blacklistHref.indexOf('assets/thirdparties/') !== 0 ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
var matches = reRepo3rdPartyAsset.exec(blacklistHref);
|
var matches = re3rdPartyRepoAsset.exec(blacklistHref);
|
||||||
if ( matches === null || matches.length !== 2 ) {
|
if ( matches === null || matches.length !== 2 ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -110,12 +111,68 @@ var renderBlacklists = function() {
|
||||||
return html.join('');
|
return html.join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats');
|
|
||||||
var purgeButtontext = chrome.i18n.getMessage('3pExternalListPurge');
|
var purgeButtontext = chrome.i18n.getMessage('3pExternalListPurge');
|
||||||
var updateButtontext = chrome.i18n.getMessage('3pExternalListNew');
|
var updateButtontext = chrome.i18n.getMessage('3pExternalListNew');
|
||||||
var obsoleteButtontext = chrome.i18n.getMessage('3pExternalListObsolete');
|
var obsoleteButtontext = chrome.i18n.getMessage('3pExternalListObsolete');
|
||||||
|
var liTemplate = [
|
||||||
|
'<li class="listDetails">',
|
||||||
|
'<input type="checkbox" {{checked}}>',
|
||||||
|
' ',
|
||||||
|
'<a href="{{URL}}" type="text/plain">',
|
||||||
|
'{{name}}',
|
||||||
|
'\u200E</a>',
|
||||||
|
'{{homeURL}}',
|
||||||
|
': ',
|
||||||
|
'<span class="dim">',
|
||||||
|
chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats'),
|
||||||
|
'</span>'
|
||||||
|
].join('');
|
||||||
|
|
||||||
var htmlFromBranch = function(groupKey, listKeys, lists) {
|
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}}', htmlFromListName(list.title, listKey))
|
||||||
|
.replace('{{homeURL}}', htmlFromHomeURL(listKey))
|
||||||
|
.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
|
||||||
|
var asset = listDetails.cache[listKey];
|
||||||
|
if ( asset === undefined ) {
|
||||||
|
return html.join('\n');
|
||||||
|
}
|
||||||
|
// Update status
|
||||||
|
if ( list.off !== true ) {
|
||||||
|
var obsolete = asset.repoObsolete ||
|
||||||
|
asset.cacheObsolete ||
|
||||||
|
asset.cached !== true && re3rdPartyExternalAsset.test(listKey);
|
||||||
|
if ( obsolete ) {
|
||||||
|
html.push(
|
||||||
|
' ',
|
||||||
|
'<span class="status obsolete">',
|
||||||
|
asset.repoObsolete ? updateButtontext : obsoleteButtontext,
|
||||||
|
'</span>'
|
||||||
|
);
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// In cache
|
||||||
|
if ( asset.cached ) {
|
||||||
|
html.push(
|
||||||
|
' ',
|
||||||
|
'<span class="status purge">',
|
||||||
|
purgeButtontext,
|
||||||
|
'</span>'
|
||||||
|
);
|
||||||
|
hasCachedContent = true;
|
||||||
|
}
|
||||||
|
return html.join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
var htmlFromBranch = function(groupKey, listKeys) {
|
||||||
var html = [
|
var html = [
|
||||||
'<li>',
|
'<li>',
|
||||||
chrome.i18n.getMessage('3pGroup' + groupKey.charAt(0).toUpperCase() + groupKey.slice(1)),
|
chrome.i18n.getMessage('3pGroup' + groupKey.charAt(0).toUpperCase() + groupKey.slice(1)),
|
||||||
|
@ -125,63 +182,10 @@ var renderBlacklists = function() {
|
||||||
return html.join('');
|
return html.join('');
|
||||||
}
|
}
|
||||||
listKeys.sort(function(a, b) {
|
listKeys.sort(function(a, b) {
|
||||||
return lists[a].title.localeCompare(lists[b].title);
|
return listDetails.available[a].title.localeCompare(listDetails.available[b].title);
|
||||||
});
|
});
|
||||||
var listEntryTemplate = [
|
|
||||||
'<li class="listDetails">',
|
|
||||||
'<input type="checkbox" {{checked}}>',
|
|
||||||
' ',
|
|
||||||
'<a href="{{URL}}" type="text/plain">',
|
|
||||||
'{{name}}',
|
|
||||||
'\u200E</a>',
|
|
||||||
'{{homeURL}}',
|
|
||||||
': ',
|
|
||||||
'<span class="dim">',
|
|
||||||
listStatsTemplate,
|
|
||||||
'</span>'
|
|
||||||
].join('');
|
|
||||||
var listKey, list, listEntry, entryDetails, obsolete;
|
|
||||||
for ( var i = 0; i < listKeys.length; i++ ) {
|
for ( var i = 0; i < listKeys.length; i++ ) {
|
||||||
listKey = listKeys[i];
|
html.push(htmlFromLeaf(listKeys[i]));
|
||||||
list = lists[listKey];
|
|
||||||
listEntry = listEntryTemplate
|
|
||||||
.replace('{{checked}}', list.off ? '' : 'checked')
|
|
||||||
.replace('{{URL}}', encodeURI(listKey))
|
|
||||||
.replace('{{name}}', htmlFromListName(list.title, listKey))
|
|
||||||
.replace('{{homeURL}}', htmlFromHomeURL(listKey))
|
|
||||||
.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
|
|
||||||
entryDetails = listDetails.cache[listKey];
|
|
||||||
if ( entryDetails === undefined ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Update status
|
|
||||||
if ( list.off !== true ) {
|
|
||||||
obsolete = entryDetails.repoObsolete ||
|
|
||||||
entryDetails.cacheObsolete ||
|
|
||||||
entryDetails.cached !== true && reExternalAsset.test(listKey);
|
|
||||||
if ( obsolete ) {
|
|
||||||
html.push(
|
|
||||||
' ',
|
|
||||||
'<span class="status obsolete">',
|
|
||||||
entryDetails.repoObsolete ? updateButtontext : obsoleteButtontext,
|
|
||||||
'</span>'
|
|
||||||
);
|
|
||||||
needUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// In cache
|
|
||||||
if ( entryDetails.cached ) {
|
|
||||||
html.push(
|
|
||||||
' ',
|
|
||||||
'<span class="status purge">',
|
|
||||||
purgeButtontext,
|
|
||||||
'</span>'
|
|
||||||
);
|
|
||||||
hasCachedContent = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
html.push('</ul>');
|
html.push('</ul>');
|
||||||
return html.join('');
|
return html.join('');
|
||||||
|
@ -207,14 +211,15 @@ var renderBlacklists = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var onListsReceived = function(details) {
|
var onListsReceived = function(details) {
|
||||||
|
// Before all, set context vars
|
||||||
listDetails = details;
|
listDetails = details;
|
||||||
cosmeticSwitch = details.cosmetic;
|
cosmeticSwitch = details.cosmetic;
|
||||||
needUpdate = false;
|
needUpdate = false;
|
||||||
hasCachedContent = false;
|
hasCachedContent = false;
|
||||||
|
|
||||||
var lists = details.available;
|
// Visually split the filter lists in purpose-based groups
|
||||||
var html = [];
|
var html = [];
|
||||||
var groups = groupsFromLists(lists);
|
var groups = groupsFromLists(details.available);
|
||||||
var groupKey, i;
|
var groupKey, i;
|
||||||
var groupKeys = [
|
var groupKeys = [
|
||||||
'default',
|
'default',
|
||||||
|
@ -228,14 +233,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], lists));
|
html.push(htmlFromBranch(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], lists));
|
html.push(htmlFromBranch(groupKey, groups[groupKey]));
|
||||||
delete groups[groupKey];
|
delete groups[groupKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,9 +312,10 @@ var listsContentChanged = function() {
|
||||||
// This is to give a visual hint that the selection of blacklists has changed.
|
// This is to give a visual hint that the selection of blacklists has changed.
|
||||||
|
|
||||||
var updateWidgets = function() {
|
var updateWidgets = function() {
|
||||||
uDom('#buttonApply').toggleClass('enabled', listsSelectionChanged());
|
uDom('#buttonApply').toggleClass('disabled', !listsSelectionChanged());
|
||||||
uDom('#buttonUpdate').toggleClass('enabled', listsContentChanged());
|
uDom('#buttonUpdate').toggleClass('disabled', !listsContentChanged());
|
||||||
uDom('#buttonPurgeAll').toggleClass('enabled', hasCachedContent);
|
uDom('#buttonPurgeAll').toggleClass('disabled', !hasCachedContent);
|
||||||
|
uDom('body').toggleClass('busy', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -356,9 +362,9 @@ var onPurgeClicked = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var reloadAll = function(update) {
|
var reloadAll = function(update) {
|
||||||
// Loading may take a while when resoruces are fetched from remote
|
// Loading may take a while when resources are fetched from remote
|
||||||
// servers. We do not want the user to force reload while we are reloading.
|
// servers. We do not want the user to force reload while we are reloading.
|
||||||
uDom('body').toggleClass('loading', true);
|
uDom('body').toggleClass('busy', true);
|
||||||
|
|
||||||
// Reload blacklists
|
// Reload blacklists
|
||||||
messaging.tell({
|
messaging.tell({
|
||||||
|
@ -465,7 +471,6 @@ var externalListsApplyHandler = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uDom.onLoad(function() {
|
uDom.onLoad(function() {
|
||||||
// Handle user interaction
|
|
||||||
uDom('#autoUpdate').on('change', autoUpdateCheckboxChanged);
|
uDom('#autoUpdate').on('change', autoUpdateCheckboxChanged);
|
||||||
uDom('#parseCosmeticFilters').on('change', cosmeticSwitchChanged);
|
uDom('#parseCosmeticFilters').on('change', cosmeticSwitchChanged);
|
||||||
uDom('#buttonApply').on('click', buttonApplyHandler);
|
uDom('#buttonApply').on('click', buttonApplyHandler);
|
||||||
|
|
Loading…
Reference in New Issue