mirror of https://github.com/gorhill/uBlock.git
parent
be27b7aa55
commit
fb62bbc29e
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>HTTP Switchboard — Ubiquitous rules</title>
|
||||
<title>µBlock — Your filters</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/common.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
|
||||
<style>
|
||||
|
@ -33,7 +33,7 @@ div > p:last-child {
|
|||
<p><button id="userFiltersApply" disabled="true" data-i18n="1pApplyChanges"></button></p>
|
||||
</div>
|
||||
|
||||
<script src="lib/jquery-2.min.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard-common.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
|
|
|
@ -33,7 +33,7 @@ ul > li {
|
|||
|
||||
<body>
|
||||
|
||||
<p id="3pListsOfBlockedHostsPrompt2"></p>
|
||||
<p id="listsOfBlockedHostsPrompt"></p>
|
||||
<ul id="blacklistTemplate" style="display:none">
|
||||
<li class="blacklistDetails"><input type="checkbox"> <a href="" type="text/plain"></a>:
|
||||
<span class="dim"></span>
|
||||
|
@ -46,7 +46,7 @@ ul > li {
|
|||
<li style="margin-top:0.75em"><button id="blacklistsApply" disabled="true" data-i18n="3pApplyChanges"></button>
|
||||
</ul>
|
||||
|
||||
<script src="lib/jquery-2.min.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard-common.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "Deine Filter",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistics",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "Über",
|
||||
"description": "appears as tab name in dashboard"
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "{{ubiquitousBlacklistCount}} eindeutig blockierte Hostnamen aus:",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Enable the logging of blocked requests",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "No blocked requests logged for this page",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Changelog'>Changelog</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "Your filters",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistics",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "About",
|
||||
"description": "appears as tab name in dashboard."
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "{{ubiquitousBlacklistCount}} network filters from:",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} network filters from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Enable the logging of blocked requests",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "No blocked requests logged for this page",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "Vos règles",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistiques",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "À propos",
|
||||
"description": "appears as tab name in dashboard"
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "{{ubiquitousBlacklistCount}} filtres actuellement en action :",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} network filters from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Activer le journal des requêtes bloquées",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "Il n'y a aucune requête bloquée dans le journal",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Journal des changements (en Anglais)</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "I tuoi filtri",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistics",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "Info",
|
||||
"description": "appears as tab name in dashboard."
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "{{ubiquitousBlacklistCount}} reti filtrate da:",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} network filters from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Enable the logging of blocked requests",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "No blocked requests logged for this page",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "Your filters",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistics",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "О расширении",
|
||||
"description": "appears as tab name in dashboard."
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "{{ubiquitousBlacklistCount}} блокируется хостов, помимо:",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Enable the logging of blocked requests",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "No blocked requests logged for this page",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Список изменений</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
"message": "Your filters",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"statsPageName" : {
|
||||
"message": "Statistics",
|
||||
"description": "appears as tab name in dashboard."
|
||||
},
|
||||
"aboutPageName": {
|
||||
"message": "关于",
|
||||
"description": "appears as tab name in dashboard."
|
||||
|
@ -53,7 +57,7 @@
|
|||
},
|
||||
|
||||
|
||||
"3pListsOfBlockedHostsPrompt2" : {
|
||||
"3pListsOfBlockedHostsPrompt" : {
|
||||
"message": "共{{ubiquitousBlacklistCount}}个不同的屏蔽站点名,来自:",
|
||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
||||
},
|
||||
|
@ -101,6 +105,20 @@
|
|||
},
|
||||
|
||||
|
||||
"logBlockedRequestsPrompt" : {
|
||||
"message": "Enable the logging of blocked requests",
|
||||
"description": "English: Enable the logging of blocked requests"
|
||||
},
|
||||
"logBlockedRequestsHelp" : {
|
||||
"message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.",
|
||||
"description": "English: see _locales/en/messages.log"
|
||||
},
|
||||
"logBlockedRequestsEmpty" : {
|
||||
"message": "No blocked requests logged for this page",
|
||||
"description": "English: No blocked requests logged for this page"
|
||||
},
|
||||
|
||||
|
||||
"aboutChangelog" : {
|
||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>变更日志</a>",
|
||||
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||
|
|
|
@ -81,7 +81,7 @@ table td:first-child {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="lib/jquery-2.min.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard-common.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
body {
|
||||
margin: 0;
|
||||
padding: 0 0.5em 5em 0.5em;
|
||||
font: 15px sans-serif;
|
||||
font: 14px sans-serif;
|
||||
}
|
||||
h2, h3 {
|
||||
margin: 1em 0;
|
||||
|
|
|
@ -27,7 +27,7 @@ body {
|
|||
#dashboard-nav-widgets {
|
||||
margin: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 4px 0 3px 0;
|
||||
padding: 4px 0 4px 0;
|
||||
white-space: nowrap;
|
||||
background-color: white;
|
||||
}
|
||||
|
@ -76,16 +76,17 @@ iframe {
|
|||
<div id="dashboard-nav">
|
||||
<div id="dashboard-nav-widgets">
|
||||
<span>µBlock</span>
|
||||
<a class="tabButton" id="thirdparty-filters" href="#thirdparty-filters" data-dashboard-panel-url="3p-filters.html" data-i18n="3pPageName"></a>
|
||||
<a class="tabButton" id="firstparty-filters" href="#firstparty-filters" data-dashboard-panel-url="1p-filters.html" data-i18n="1pPageName"></a>
|
||||
<a class="tabButton" id="settings" href="#settings" data-dashboard-panel-url="settings.html" data-i18n="settingsPageName"></a>
|
||||
<a class="tabButton" id="about" href="#about" data-dashboard-panel-url="about.html" data-i18n="aboutPageName"></a>
|
||||
<a class="tabButton" href="#" data-dashboard-panel-url="3p-filters.html" data-i18n="3pPageName"></a>
|
||||
<a class="tabButton" href="#" data-dashboard-panel-url="1p-filters.html" data-i18n="1pPageName"></a>
|
||||
<a class="tabButton" href="#" data-dashboard-panel-url="settings.html" data-i18n="settingsPageName"></a>
|
||||
<a class="tabButton" href="#" data-dashboard-panel-url="stats.html" data-i18n="statsPageName"></a>
|
||||
<a class="tabButton" href="#" data-dashboard-panel-url="about.html" data-i18n="aboutPageName"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<iframe src=""></iframe>
|
||||
|
||||
<script src="lib/jquery-2.min.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global chrome, $ */
|
||||
/* global chrome, messaging, uDom */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -37,11 +37,10 @@ messaging.start('1p-filters.js');
|
|||
|
||||
// This is to give a visual hint that the content of user blacklist has changed.
|
||||
|
||||
function userFiltersChanged() {
|
||||
$('#userFiltersApply')
|
||||
.attr(
|
||||
function userFiltersChanged(ev) {
|
||||
uDom('#userFiltersApply').prop(
|
||||
'disabled',
|
||||
$('#userFilters').val().trim() === cachedUserFilters
|
||||
uDom('#userFilters').val().trim() === cachedUserFilters
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -53,7 +52,7 @@ function renderUserFilters() {
|
|||
return;
|
||||
}
|
||||
cachedUserFilters = details.content.trim();
|
||||
$('#userFilters').val(details.content);
|
||||
uDom('#userFilters').val(details.content);
|
||||
};
|
||||
messaging.ask({ what: 'readUserFilters' }, onRead);
|
||||
}
|
||||
|
@ -62,23 +61,22 @@ function renderUserFilters() {
|
|||
|
||||
function allFiltersApplyHandler() {
|
||||
messaging.tell({ what: 'reloadAllFilters' });
|
||||
$('#userFiltersApply').attr('disabled', true );
|
||||
uDom('#userFiltersApply').prop('disabled', true );
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function appendToUserFiltersFromFile() {
|
||||
var input = $('<input />').attr({
|
||||
var input = uDom('<input />').attr({
|
||||
type: 'file',
|
||||
accept: 'text/plain'
|
||||
});
|
||||
var fileReaderOnLoadHandler = function() {
|
||||
var textarea = $('#userFilters');
|
||||
textarea.val(textarea.val() + '\n' + this.result);
|
||||
var textarea = uDom('#userFilters');
|
||||
textarea.val([textarea.val(), this.result].join('\n').trim());
|
||||
userFiltersChanged();
|
||||
};
|
||||
var filePickerOnChangeHandler = function() {
|
||||
$(this).off('change', filePickerOnChangeHandler);
|
||||
var file = this.files[0];
|
||||
if ( !file ) {
|
||||
return;
|
||||
|
@ -99,7 +97,7 @@ function appendToUserFiltersFromFile() {
|
|||
|
||||
function exportUserFiltersToFile() {
|
||||
chrome.downloads.download({
|
||||
'url': 'data:text/plain,' + encodeURIComponent($('#userFilters').val()),
|
||||
'url': 'data:text/plain,' + encodeURIComponent(uDom('#userFilters').val()),
|
||||
'filename': 'my-ublock-filters.txt',
|
||||
'saveAs': true
|
||||
});
|
||||
|
@ -118,19 +116,19 @@ function userFiltersApplyHandler() {
|
|||
};
|
||||
var request = {
|
||||
what: 'writeUserFilters',
|
||||
content: $('#userFilters').val()
|
||||
content: uDom('#userFilters').val()
|
||||
};
|
||||
messaging.ask(request, onWritten);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
$(function() {
|
||||
uDom.onLoad(function() {
|
||||
// Handle user interaction
|
||||
$('#importUserFiltersFromFile').on('click', appendToUserFiltersFromFile);
|
||||
$('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
|
||||
$('#userFilters').on('input propertychange', userFiltersChanged);
|
||||
$('#userFiltersApply').on('click', userFiltersApplyHandler);
|
||||
uDom('#importUserFiltersFromFile').on('click', appendToUserFiltersFromFile);
|
||||
uDom('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
|
||||
uDom('#userFilters').on('input', userFiltersChanged);
|
||||
uDom('#userFiltersApply').on('click', userFiltersApplyHandler);
|
||||
|
||||
renderUserFilters();
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global chrome, $ */
|
||||
/* global chrome, messaging, uDom */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -28,8 +28,6 @@
|
|||
/******************************************************************************/
|
||||
|
||||
var userListName = chrome.i18n.getMessage('1pPageName');
|
||||
var cachedUserUbiquitousBlacklistedHosts = '';
|
||||
var cachedUserUbiquitousWhitelistedHosts = '';
|
||||
var selectedBlacklistsHash = '';
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -77,12 +75,12 @@ function renderNumber(value) {
|
|||
|
||||
function renderBlacklists() {
|
||||
// empty list first
|
||||
$('#blacklists .blacklistDetails').remove();
|
||||
uDom('#blacklists .blacklistDetails').remove();
|
||||
|
||||
var µb = getµb();
|
||||
|
||||
$('#3pListsOfBlockedHostsPrompt2').text(
|
||||
chrome.i18n.getMessage('3pListsOfBlockedHostsPrompt2')
|
||||
uDom('#listsOfBlockedHostsPrompt').text(
|
||||
chrome.i18n.getMessage('3pListsOfBlockedHostsPrompt')
|
||||
.replace('{{ubiquitousBlacklistCount}}', renderNumber(µb.abpFilters.getFilterCount()))
|
||||
);
|
||||
|
||||
|
@ -119,31 +117,29 @@ function renderBlacklists() {
|
|||
|
||||
var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats');
|
||||
var blacklists = µb.remoteBlacklists;
|
||||
var ul = $('#blacklists');
|
||||
var ul = uDom('#blacklists');
|
||||
var keys = Object.keys(blacklists);
|
||||
var i = keys.length;
|
||||
var blacklist, blacklistHref;
|
||||
var liTemplate = $('#blacklistTemplate .blacklistDetails').first();
|
||||
var li, child, text;
|
||||
var liTemplate = uDom('#blacklistTemplate .blacklistDetails').first();
|
||||
var li, text;
|
||||
while ( i-- ) {
|
||||
blacklistHref = keys[i];
|
||||
blacklist = blacklists[blacklistHref];
|
||||
li = liTemplate.clone();
|
||||
child = $('input', li);
|
||||
child.prop('checked', !blacklist.off);
|
||||
child = $('a', li);
|
||||
child.attr('href', encodeURI(blacklistHref));
|
||||
child.html(prettifyListName(blacklist.title, blacklistHref));
|
||||
child = $('span', li);
|
||||
li.find('input').prop('checked', !blacklist.off);
|
||||
li.find('a')
|
||||
.attr('href', encodeURI(blacklistHref))
|
||||
.html(prettifyListName(blacklist.title, blacklistHref));
|
||||
text = listStatsTemplate
|
||||
.replace('{{used}}', !blacklist.off && !isNaN(+blacklist.entryUsedCount) ? renderNumber(blacklist.entryUsedCount) : '0')
|
||||
.replace('{{total}}', !isNaN(+blacklist.entryCount) ? renderNumber(blacklist.entryCount) : '?')
|
||||
;
|
||||
child.text(text);
|
||||
li.find('span').text(text);
|
||||
ul.prepend(li);
|
||||
}
|
||||
$('#parseAllABPHideFilters').attr('checked', µb.userSettings.parseAllABPHideFilters === true);
|
||||
$('#ubiquitousParseAllABPHideFiltersPrompt2').text(
|
||||
uDom('#parseAllABPHideFilters').attr('checked', µb.userSettings.parseAllABPHideFilters === true);
|
||||
uDom('#ubiquitousParseAllABPHideFiltersPrompt2').text(
|
||||
chrome.i18n.getMessage("listsParseAllABPHideFiltersPrompt2")
|
||||
.replace('{{abpHideFilterCount}}', renderNumber(µb.abpHideFilters.getFilterCount()))
|
||||
);
|
||||
|
@ -158,15 +154,13 @@ function renderBlacklists() {
|
|||
|
||||
function getSelectedBlacklistsHash() {
|
||||
var hash = '';
|
||||
var inputs = $('#blacklists .blacklistDetails > input');
|
||||
var i = inputs.length;
|
||||
var entryHash;
|
||||
var inputs = uDom('#blacklists .blacklistDetails > input');
|
||||
var i = inputs.length();
|
||||
while ( i-- ) {
|
||||
entryHash = $(inputs[i]).prop('checked').toString();
|
||||
hash += entryHash;
|
||||
hash += inputs.subset(i).prop('checked').toString();
|
||||
}
|
||||
// Factor in whether ABP filters are to be processed
|
||||
hash += $('#parseAllABPHideFilters').prop('checked').toString();
|
||||
// Factor in whether cosmetic filters are to be processed
|
||||
hash += uDom('#parseAllABPHideFilters').prop('checked').toString();
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
@ -176,7 +170,7 @@ function getSelectedBlacklistsHash() {
|
|||
// This is to give a visual hint that the selection of blacklists has changed.
|
||||
|
||||
function selectedBlacklistsChanged() {
|
||||
$('#blacklistsApply').attr(
|
||||
uDom('#blacklistsApply').prop(
|
||||
'disabled',
|
||||
getSelectedBlacklistsHash() === selectedBlacklistsHash
|
||||
);
|
||||
|
@ -191,21 +185,21 @@ function blacklistsApplyHandler() {
|
|||
}
|
||||
// Reload blacklists
|
||||
var switches = [];
|
||||
var lis = $('#blacklists .blacklistDetails');
|
||||
var i = lis.length;
|
||||
var lis = uDom('#blacklists .blacklistDetails');
|
||||
var i = lis.length();
|
||||
var path;
|
||||
while ( i-- ) {
|
||||
path = $(lis[i]).children('a').attr('href');
|
||||
path = lis.subset(i).find('a').attr('href');
|
||||
switches.push({
|
||||
location: path,
|
||||
off: $(lis[i]).children('input').prop('checked') === false
|
||||
off: lis.subset(i).find('input').prop('checked') === false
|
||||
});
|
||||
}
|
||||
messaging.tell({
|
||||
what: 'reloadAllFilters',
|
||||
switches: switches
|
||||
});
|
||||
$('#blacklistsApply').attr('disabled', true );
|
||||
uDom('#blacklistsApply').attr('disabled', true );
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -214,18 +208,18 @@ function abpHideFiltersCheckboxChanged() {
|
|||
messaging.tell({
|
||||
what: 'userSettings',
|
||||
name: 'parseAllABPHideFilters',
|
||||
value: $(this).is(':checked')
|
||||
value: this.checked
|
||||
});
|
||||
selectedBlacklistsChanged();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
uDom.onLoad(function() {
|
||||
// Handle user interaction
|
||||
$('#blacklists').on('change', '.blacklistDetails', selectedBlacklistsChanged);
|
||||
$('#blacklistsApply').on('click', blacklistsApplyHandler);
|
||||
$('#parseAllABPHideFilters').on('change', abpHideFiltersCheckboxChanged);
|
||||
uDom('#blacklists').on('change', '.blacklistDetails', selectedBlacklistsChanged);
|
||||
uDom('#blacklistsApply').on('click', blacklistsApplyHandler);
|
||||
uDom('#parseAllABPHideFilters').on('change', abpHideFiltersCheckboxChanged);
|
||||
|
||||
renderBlacklists();
|
||||
});
|
||||
|
|
36
js/about.js
36
js/about.js
|
@ -19,11 +19,11 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global chrome, $ */
|
||||
/* global chrome, messaging, uDom */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
uDom.onLoad(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -35,7 +35,7 @@ var commitHistoryURLPrefix = 'https://github.com/gorhill/ublock/commits/master/'
|
|||
|
||||
var setAssetListClassBit = function(bit, state) {
|
||||
assetListSwitches[assetListSwitches.length-1-bit] = !state ? 'o' : 'x';
|
||||
$('#assetList')
|
||||
uDom('#assetList')
|
||||
.removeClass()
|
||||
.addClass(assetListSwitches.join(''));
|
||||
};
|
||||
|
@ -46,24 +46,24 @@ var renderAssetList = function(details) {
|
|||
var dirty = false;
|
||||
var paths = Object.keys(details.list).sort();
|
||||
if ( paths.length > 0 ) {
|
||||
$('#assetList .assetEntry').remove();
|
||||
var assetTable = $('#assetList table');
|
||||
uDom('#assetList .assetEntry').remove();
|
||||
var i = 0;
|
||||
var path, status, html;
|
||||
var path, status, html = [];
|
||||
while ( path = paths[i++] ) {
|
||||
status = details.list[path].status;
|
||||
dirty = dirty || status !== 'Unchanged';
|
||||
html = [];
|
||||
html.push('<tr class="assetEntry ' + status.toLowerCase().replace(/ +/g, '-') + '">');
|
||||
html.push('<td>');
|
||||
html.push('<a href="' + commitHistoryURLPrefix + path + '">');
|
||||
html.push(path.replace(/^(assets\/[^/]+\/)(.+)$/, '$1<b>$2</b>'));
|
||||
html.push('</a>');
|
||||
html.push('<td>');
|
||||
html.push(chrome.i18n.getMessage('aboutAssetsUpdateStatus' + status));
|
||||
assetTable.append(html.join(''));
|
||||
html.push(
|
||||
'<tr class="assetEntry ' + status.toLowerCase().replace(/ +/g, '-') + '">',
|
||||
'<td>',
|
||||
'<a href="' + commitHistoryURLPrefix + path + '">',
|
||||
path.replace(/^(assets\/[^/]+\/)(.+)$/, '$1<b>$2</b>'),
|
||||
'</a>',
|
||||
'<td>',
|
||||
chrome.i18n.getMessage('aboutAssetsUpdateStatus' + status)
|
||||
);
|
||||
}
|
||||
$('#assetList a').attr('target', '_blank');
|
||||
uDom('#assetList table tBody').append(html.join(''));
|
||||
uDom('#assetList a').attr('target', '_blank');
|
||||
updateList = details.list;
|
||||
}
|
||||
setAssetListClassBit(0, paths.length !== 0);
|
||||
|
@ -110,8 +110,8 @@ messaging.listen(onAnnounce);
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
$('#aboutVersion').html(chrome.runtime.getManifest().version);
|
||||
$('#aboutAssetsUpdateButton').on('click', updateAssets);
|
||||
uDom('#aboutVersion').html(chrome.runtime.getManifest().version);
|
||||
uDom('#aboutAssetsUpdateButton').on('click', updateAssets);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
@ -600,16 +600,11 @@ FilterContainer.prototype.retrieveGenericSelectors = function(tabHostname, reque
|
|||
|
||||
//quickProfiler.stop();
|
||||
|
||||
/*
|
||||
console.log(
|
||||
'µBlock> abp-hide-filters.js: "%s"\n\t%d selectors in => %d/%d filters/buckets tested => %d selectors out',
|
||||
url,
|
||||
inSelectors.length,
|
||||
//filterTestCount,
|
||||
//bucketTestCount,
|
||||
hideSelectors.length + donthideSelectors.length
|
||||
);
|
||||
*/
|
||||
//console.log(
|
||||
// 'µBlock> abp-hide-filters.js: %d selectors in => %d selectors out',
|
||||
// request.selectors.length,
|
||||
// r.hide.length + r.donthide.length
|
||||
//);
|
||||
|
||||
return r;
|
||||
};
|
||||
|
@ -656,16 +651,11 @@ FilterContainer.prototype.retrieveDomainSelectors = function(tabHostname, reques
|
|||
|
||||
//quickProfiler.stop();
|
||||
|
||||
/*
|
||||
console.log(
|
||||
'µBlock> abp-hide-filters.js: "%s"\n\t%d selectors in => %d/%d filters/buckets tested => %d selectors out',
|
||||
url,
|
||||
inSelectors.length,
|
||||
//filterTestCount,
|
||||
//bucketTestCount,
|
||||
hideSelectors.length + donthideSelectors.length
|
||||
);
|
||||
*/
|
||||
//console.log(
|
||||
// 'µBlock> abp-hide-filters.js: "%s" => %d selectors out',
|
||||
// request.locationURL,
|
||||
// r.hide.length + r.donthide.length
|
||||
//);
|
||||
|
||||
return r;
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@ return {
|
|||
|
||||
userSettings: {
|
||||
collapseBlocked: true,
|
||||
logBlockedRequests: false,
|
||||
parseAllABPHideFilters: true,
|
||||
netExceptionList: {},
|
||||
showIconBadge: true
|
||||
|
@ -41,7 +42,7 @@ return {
|
|||
allowedRequestCount: 0
|
||||
},
|
||||
|
||||
updateAssetsEvery: 5 * 24 * 60 * 60 * 1000,
|
||||
updateAssetsEvery: 4 * 24 * 60 * 60 * 1000,
|
||||
projectServerRoot: 'https://raw2.github.com/gorhill/ublock/master/',
|
||||
userFiltersPath: 'assets/user/filters.txt',
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/httpswitchboard/issues/345
|
||||
|
||||
var messaging = (function(name){
|
||||
|
@ -121,20 +125,16 @@ var messaging = (function(name){
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// ABP cosmetic filters
|
||||
|
||||
var CosmeticFiltering = function() {
|
||||
this.queriedSelectors = {};
|
||||
this.injectedSelectors = {};
|
||||
this.classSelectors = null;
|
||||
this.idSelectors = null;
|
||||
};
|
||||
var cosmeticFiltering = (function() {
|
||||
|
||||
CosmeticFiltering.prototype.onDOMContentLoaded = function() {
|
||||
var queriedSelectors = {};
|
||||
var injectedSelectors = {};
|
||||
var classSelectors = null;
|
||||
var idSelectors = null;
|
||||
|
||||
var domLoaded = function() {
|
||||
// https://github.com/gorhill/uBlock/issues/14
|
||||
// Treat any existing domain-specific exception selectors as if they had
|
||||
// been injected already.
|
||||
|
@ -144,20 +144,19 @@ CosmeticFiltering.prototype.onDOMContentLoaded = function() {
|
|||
exceptions = decodeURIComponent(exceptions).split('\n');
|
||||
var i = exceptions.length;
|
||||
while ( i-- ) {
|
||||
this.injectedSelectors[exceptions[i]] = true;
|
||||
injectedSelectors[exceptions[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: evaluate merging into a single loop
|
||||
this.classesFromNodeList(document.querySelectorAll('*[class]'));
|
||||
this.idsFromNodeList(document.querySelectorAll('*[id]'));
|
||||
this.retrieveGenericSelectors();
|
||||
selectorsFromNodeList(document.querySelectorAll('*[class],*[id]'));
|
||||
retrieveGenericSelectors();
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.retrieveGenericSelectors = function() {
|
||||
var selectors = this.classSelectors !== null ? Object.keys(this.classSelectors) : [];
|
||||
if ( this.idSelectors !== null ) {
|
||||
selectors = selectors.concat(this.idSelectors);
|
||||
var retrieveGenericSelectors = function() {
|
||||
var selectors = classSelectors !== null ? Object.keys(classSelectors) : [];
|
||||
if ( idSelectors !== null ) {
|
||||
selectors = selectors.concat(idSelectors);
|
||||
}
|
||||
if ( selectors.length > 0 ) {
|
||||
//console.log('µBlock> ABP cosmetic filters: retrieving CSS rules using %d selectors', selectors.length);
|
||||
|
@ -166,34 +165,34 @@ CosmeticFiltering.prototype.retrieveGenericSelectors = function() {
|
|||
pageURL: window.location.href,
|
||||
selectors: selectors
|
||||
},
|
||||
this.retrieveHandler.bind(this)
|
||||
retrieveHandler
|
||||
);
|
||||
}
|
||||
this.idSelectors = null;
|
||||
this.classSelectors = null;
|
||||
idSelectors = null;
|
||||
classSelectors = null;
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.retrieveHandler = function(selectors) {
|
||||
var retrieveHandler = function(selectors) {
|
||||
if ( !selectors ) {
|
||||
return;
|
||||
}
|
||||
var styleText = [];
|
||||
this.filterUnfiltered(selectors.hideUnfiltered, selectors.hide);
|
||||
this.reduce(selectors.hide, this.injectedSelectors);
|
||||
filterUnfiltered(selectors.hideUnfiltered, selectors.hide);
|
||||
reduce(selectors.hide, injectedSelectors);
|
||||
if ( selectors.hide.length ) {
|
||||
var hideStyleText = '{{hideSelectors}} {display:none !important;}'
|
||||
.replace('{{hideSelectors}}', selectors.hide.join(','));
|
||||
styleText.push(hideStyleText);
|
||||
this.applyCSS(selectors.hide, 'display', 'none');
|
||||
applyCSS(selectors.hide, 'display', 'none');
|
||||
//console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.hide.length, hideStyleText);
|
||||
}
|
||||
this.filterUnfiltered(selectors.donthideUnfiltered, selectors.donthide);
|
||||
this.reduce(selectors.donthide, this.injectedSelectors);
|
||||
filterUnfiltered(selectors.donthideUnfiltered, selectors.donthide);
|
||||
reduce(selectors.donthide, injectedSelectors);
|
||||
if ( selectors.donthide.length ) {
|
||||
var dontHideStyleText = '{{donthideSelectors}} {display:initial !important;}'
|
||||
.replace('{{donthideSelectors}}', selectors.donthide.join(','));
|
||||
styleText.push(dontHideStyleText);
|
||||
this.applyCSS(selectors.donthide, 'display', 'initial');
|
||||
applyCSS(selectors.donthide, 'display', 'initial');
|
||||
//console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.donthide.length, dontHideStyleText);
|
||||
}
|
||||
if ( styleText.length > 0 ) {
|
||||
|
@ -206,7 +205,7 @@ CosmeticFiltering.prototype.retrieveHandler = function(selectors) {
|
|||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.applyCSS = function(selectors, prop, value) {
|
||||
var applyCSS = function(selectors, prop, value) {
|
||||
if ( document.body === null ) {
|
||||
return;
|
||||
}
|
||||
|
@ -217,12 +216,12 @@ CosmeticFiltering.prototype.applyCSS = function(selectors, prop, value) {
|
|||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.filterUnfiltered = function(inSelectors, outSelectors) {
|
||||
var filterUnfiltered = function(inSelectors, outSelectors) {
|
||||
var i = inSelectors.length;
|
||||
var selector;
|
||||
while ( i-- ) {
|
||||
selector = inSelectors[i];
|
||||
if ( this.injectedSelectors[selector] ) {
|
||||
if ( injectedSelectors[selector] ) {
|
||||
continue;
|
||||
}
|
||||
if ( document.querySelector(selector) !== null ) {
|
||||
|
@ -231,7 +230,7 @@ CosmeticFiltering.prototype.filterUnfiltered = function(inSelectors, outSelector
|
|||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.reduce = function(selectors, dict) {
|
||||
var reduce = function(selectors, dict) {
|
||||
var i = selectors.length, selector, end;
|
||||
while ( i-- ) {
|
||||
selector = selectors[i];
|
||||
|
@ -250,108 +249,93 @@ CosmeticFiltering.prototype.reduce = function(selectors, dict) {
|
|||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.classesFromNodeList = function(nodes) {
|
||||
if ( !nodes ) {
|
||||
var selectorsFromNodeList = function(nodes) {
|
||||
if ( !nodes || !nodes.length ) {
|
||||
return;
|
||||
}
|
||||
if ( this.classSelectors === null ) {
|
||||
this.classSelectors = {};
|
||||
if ( idSelectors === null ) {
|
||||
idSelectors = [];
|
||||
}
|
||||
var classNames, className, j;
|
||||
if ( classSelectors === null ) {
|
||||
classSelectors = {};
|
||||
}
|
||||
var qq = queriedSelectors;
|
||||
var cc = classSelectors;
|
||||
var ii = idSelectors;
|
||||
var node, v, classNames, j;
|
||||
var i = nodes.length;
|
||||
while ( i-- ) {
|
||||
className = nodes[i].className;
|
||||
if ( typeof className !== 'string' ) {
|
||||
continue;
|
||||
}
|
||||
className = className.trim();
|
||||
if ( className === '' ) {
|
||||
continue;
|
||||
}
|
||||
if ( className.indexOf(' ') < 0 ) {
|
||||
className = '.' + className;
|
||||
if ( this.queriedSelectors[className] ) {
|
||||
continue;
|
||||
}
|
||||
this.classSelectors[className] = true;
|
||||
this.queriedSelectors[className] = true;
|
||||
continue;
|
||||
}
|
||||
classNames = className.trim().split(/\s+/);
|
||||
j = classNames.length;
|
||||
while ( j-- ) {
|
||||
className = classNames[j];
|
||||
if ( className === '' ) {
|
||||
continue;
|
||||
}
|
||||
className = '.' + className;
|
||||
if ( this.queriedSelectors[className] ) {
|
||||
continue;
|
||||
}
|
||||
this.classSelectors[className] = true;
|
||||
this.queriedSelectors[className] = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.idsFromNodeList = function(nodes) {
|
||||
if ( !nodes ) {
|
||||
return;
|
||||
}
|
||||
if ( this.idSelectors === null ) {
|
||||
this.idSelectors = [];
|
||||
}
|
||||
var id;
|
||||
var i = nodes.length;
|
||||
while ( i-- ) {
|
||||
id = nodes[i].id;
|
||||
if ( !id ) {
|
||||
continue;
|
||||
}
|
||||
id = '#' + id;
|
||||
if ( this.queriedSelectors[id] ) {
|
||||
continue;
|
||||
}
|
||||
this.idSelectors.push(id);
|
||||
this.queriedSelectors[id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
CosmeticFiltering.prototype.allFromNodeList = function(nodes) {
|
||||
this.classesFromNodeList(nodes);
|
||||
this.idsFromNodeList(nodes);
|
||||
var i = nodes.length;
|
||||
var node;
|
||||
while ( i-- ) {
|
||||
node = nodes[i];
|
||||
if ( node.querySelectorAll ) {
|
||||
this.classesFromNodeList(node.querySelectorAll('*[class]'));
|
||||
this.idsFromNodeList(node.querySelectorAll('*[id]'));
|
||||
if ( node.nodeType !== 1 ) {
|
||||
continue;
|
||||
}
|
||||
// id
|
||||
v = nodes[i].id.trim();
|
||||
if ( v !== '' ) {
|
||||
v = '#' + v;
|
||||
if ( !qq[v] ) {
|
||||
ii.push(v);
|
||||
qq[v] = true;
|
||||
}
|
||||
}
|
||||
// class
|
||||
v = nodes[i].className;
|
||||
// it could be an SVGAnimatedString...
|
||||
if ( typeof v !== 'string' ) { continue; }
|
||||
v = v.trim();
|
||||
if ( v === '' ) { continue; }
|
||||
// one class
|
||||
if ( v.indexOf(' ') < 0 ) {
|
||||
v = '.' + v;
|
||||
if ( qq[v] ) { continue; }
|
||||
cc[v] = true;
|
||||
qq[v] = true;
|
||||
continue;
|
||||
}
|
||||
// many classes
|
||||
classNames = v.trim().split(/\s+/);
|
||||
j = classNames.length;
|
||||
while ( j-- ) {
|
||||
v = classNames[j];
|
||||
if ( v === '' ) { continue; }
|
||||
v = '.' + v;
|
||||
if ( qq[v] ) { continue; }
|
||||
cc[v] = true;
|
||||
qq[v] = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var cosmeticFiltering = new CosmeticFiltering();
|
||||
var processNodeLists = function(nodeLists) {
|
||||
var i = nodeLists.length;
|
||||
var nodeList, j, node;
|
||||
while ( i-- ) {
|
||||
nodeList = nodeLists[i];
|
||||
selectorsFromNodeList(nodeList);
|
||||
j = nodeList.length;
|
||||
while ( j-- ) {
|
||||
node = nodeList[j];
|
||||
if ( node.querySelectorAll ) {
|
||||
selectorsFromNodeList(node.querySelectorAll('*[id],*[class]'));
|
||||
}
|
||||
}
|
||||
}
|
||||
retrieveGenericSelectors();
|
||||
};
|
||||
|
||||
domLoaded();
|
||||
|
||||
return {
|
||||
processNodeLists: processNodeLists
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/7
|
||||
|
||||
var observeElement = function(elem) {
|
||||
var onLoad = function() {
|
||||
var elem = this;
|
||||
var onAnswerReceived = function(details) {
|
||||
if ( details.blocked ) {
|
||||
hideBlockedElement(elem, details.collapse);
|
||||
}
|
||||
};
|
||||
messaging.ask({ what: 'blockedRequest', url: this.src }, onAnswerReceived);
|
||||
this.removeEventListener('load', onLoad);
|
||||
};
|
||||
elem.addEventListener('load', onLoad);
|
||||
};
|
||||
|
||||
var hideBlockedElement = function(elem, collapse) {
|
||||
var blockedElementHider = (function() {
|
||||
var hideOne = function(elem, collapse) {
|
||||
// If `!important` is not there, going back using history will likely
|
||||
// cause the hidden element to re-appear.
|
||||
elem.style.visibility = 'hidden !important';
|
||||
|
@ -360,7 +344,21 @@ var hideBlockedElement = function(elem, collapse) {
|
|||
}
|
||||
};
|
||||
|
||||
var hideBlockedElements = function(elems, details) {
|
||||
var observeOne = function(elem) {
|
||||
var onComplete = function() {
|
||||
var elem = this;
|
||||
var onAnswerReceived = function(details) {
|
||||
if ( details.blocked ) {
|
||||
hideOne(elem, details.collapse);
|
||||
}
|
||||
};
|
||||
messaging.ask({ what: 'blockedRequest', url: this.src }, onAnswerReceived);
|
||||
this.removeEventListener('load', onComplete);
|
||||
};
|
||||
elem.addEventListener('load', onComplete);
|
||||
};
|
||||
|
||||
var hideMany = function(elems, details) {
|
||||
var blockedRequests = details.blockedRequests;
|
||||
var collapse = details.collapse;
|
||||
var i = elems.length;
|
||||
|
@ -372,50 +370,55 @@ var hideBlockedElements = function(elems, details) {
|
|||
continue;
|
||||
}
|
||||
if ( src === '' ) {
|
||||
observeElement(elem);
|
||||
observeOne(elem);
|
||||
} else if ( blockedRequests[src] ) {
|
||||
hideBlockedElement(elem, collapse);
|
||||
hideOne(elem, collapse);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var hideBlockedElementInAddedNodes = function(nodes) {
|
||||
var onBlockedRequestsReceived = function(details) {
|
||||
hideBlockedElements(nodes, details);
|
||||
var i = nodes.length;
|
||||
var elem;
|
||||
var processElements = function(elems) {
|
||||
var blockedRequestsReceived = function(details) {
|
||||
hideMany(elems, details);
|
||||
var i = elems.length;
|
||||
while ( i-- ) {
|
||||
elem = nodes[i];
|
||||
if ( elem.querySelectorAll ) {
|
||||
hideBlockedElements(elem.querySelectorAll('img,iframe'), details);
|
||||
}
|
||||
hideMany(elems[i].querySelectorAll('img,iframe'), details);
|
||||
}
|
||||
};
|
||||
messaging.ask({ what: 'blockedRequests' }, onBlockedRequestsReceived);
|
||||
messaging.ask({ what: 'blockedRequests' }, blockedRequestsReceived);
|
||||
};
|
||||
|
||||
// rhill 2014-07-01: Avoid useless work: only nodes which are element are
|
||||
// of interest at this point -- because it is common that a lot of plain
|
||||
// text nodes get added.
|
||||
var addNodeLists = function(nodeLists) {
|
||||
var elems = [];
|
||||
var i = nodeLists.length;
|
||||
var nodeList, j, node;
|
||||
while ( i-- ) {
|
||||
nodeList = nodeLists[i];
|
||||
j = nodeList.length;
|
||||
while ( j-- ) {
|
||||
node = nodeList[j];
|
||||
if ( node.querySelectorAll ) {
|
||||
elems.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( elems.length ) {
|
||||
processElements(elems);
|
||||
}
|
||||
};
|
||||
|
||||
(function() {
|
||||
var onBlockedRequestsReceived = function(details) {
|
||||
hideBlockedElements(document.querySelectorAll('img,iframe'), details);
|
||||
hideMany(document.querySelectorAll('img,iframe'), details);
|
||||
};
|
||||
messaging.ask({ what: 'blockedRequests' }, onBlockedRequestsReceived);
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var mutationObservedHandler = function(mutations) {
|
||||
var iMutation = mutations.length;
|
||||
var mutation;
|
||||
while ( iMutation-- ) {
|
||||
mutation = mutations[iMutation];
|
||||
if ( mutation.addedNodes ) {
|
||||
cosmeticFiltering.allFromNodeList(mutation.addedNodes);
|
||||
hideBlockedElementInAddedNodes(mutation.addedNodes);
|
||||
}
|
||||
}
|
||||
|
||||
cosmeticFiltering.retrieveGenericSelectors();
|
||||
return {
|
||||
addNodeLists: addNodeLists
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -435,12 +438,23 @@ if ( /^https?:\/\/./.test(window.location.href) === false ) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
cosmeticFiltering.onDOMContentLoaded();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Observe changes in the DOM
|
||||
|
||||
var mutationObservedHandler = function(mutations) {
|
||||
var iMutation = mutations.length;
|
||||
var nodeLists = [], nodeList;
|
||||
while ( iMutation-- ) {
|
||||
nodeList = mutations[iMutation].addedNodes;
|
||||
if ( nodeList && nodeList.length ) {
|
||||
nodeLists.push(nodeList);
|
||||
}
|
||||
}
|
||||
if ( nodeLists.length ) {
|
||||
cosmeticFiltering.processNodeLists(nodeLists);
|
||||
blockedElementHider.addNodeLists(nodeLists);
|
||||
}
|
||||
};
|
||||
|
||||
// This fixes http://acid3.acidtests.org/
|
||||
if ( document.body ) {
|
||||
// https://github.com/gorhill/httpswitchboard/issues/176
|
||||
|
|
|
@ -21,20 +21,14 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uDom.onLoad(function() {
|
||||
// Open links in the proper window
|
||||
$('a').attr('target', '_blank');
|
||||
$('a[href*="dashboard.html"]').attr('target', '_parent');
|
||||
|
||||
$('.whatisthis').on('click', function() {
|
||||
$(this).parent()
|
||||
uDom('a').attr('target', '_blank');
|
||||
uDom('a[href*="dashboard.html"]').attr('target', '_parent');
|
||||
uDom('.whatisthis').on('click', function() {
|
||||
uDom(this)
|
||||
.parent()
|
||||
.find('.whatisthis-expandable')
|
||||
.toggleClass('whatisthis-expanded');
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
});
|
||||
|
|
|
@ -23,31 +23,41 @@
|
|||
|
||||
(function() {
|
||||
|
||||
var loadDashboardPanel = function(hash) {
|
||||
var button = $(hash);
|
||||
var url = button.data('dashboardPanelUrl');
|
||||
$('iframe')[0].src = url;
|
||||
$('.tabButton').each(function(){
|
||||
var button = $(this);
|
||||
button.toggleClass('selected', button.data('dashboardPanelUrl') === url);
|
||||
});
|
||||
/******************************************************************************/
|
||||
|
||||
var loadDashboardPanel = function(tab) {
|
||||
var tabButton = uDom('[data-dashboard-panel-url="' + tab + '"]');
|
||||
if ( !tabButton ) {
|
||||
return;
|
||||
}
|
||||
uDom('iframe').attr('src', tab);
|
||||
uDom('.tabButton').toggleClass('selected', false);
|
||||
tabButton.toggleClass('selected', true);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onTabClickHandler = function() {
|
||||
loadDashboardPanel(window.location.hash);
|
||||
}
|
||||
loadDashboardPanel(uDom(this).attr('data-dashboard-panel-url'));
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
$(function() {
|
||||
$(window).on('hashchange', onTabClickHandler);
|
||||
var hash = window.location.hash;
|
||||
if ( hash.length < 2 ) {
|
||||
hash = '#thirdparty-filters';
|
||||
uDom.onLoad(function() {
|
||||
var matches = window.location.search.slice(1).match(/\??(tab=([^&]+))?(.*)$/);
|
||||
var tab = '', q = '';
|
||||
if ( matches && matches.length === 4 ) {
|
||||
tab = matches[2];
|
||||
q = matches[3];
|
||||
if ( q !== '' && q.charAt(0) === '&' ) {
|
||||
q = '?' + q.slice(1);
|
||||
}
|
||||
loadDashboardPanel(hash);
|
||||
}
|
||||
if ( !tab ) {
|
||||
tab = '3p-filters';
|
||||
}
|
||||
loadDashboardPanel(tab + '.html' + q);
|
||||
uDom('.tabButton').on('click', onTabClickHandler);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
15
js/i18n.js
15
js/i18n.js
|
@ -20,18 +20,11 @@
|
|||
*/
|
||||
|
||||
// Helper to deal with the i18n'ing of HTML files.
|
||||
// jQuery must be present at this point.
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var i;
|
||||
var fillin = function(elem) {
|
||||
var key = elem.getAttribute("data-i18n");
|
||||
elem.innerHTML = chrome.i18n.getMessage(key);
|
||||
uDom.onLoad(function() {
|
||||
var fillin = function() {
|
||||
this.innerHTML = chrome.i18n.getMessage(this.getAttribute('data-i18n'));
|
||||
}
|
||||
|
||||
var elems = document.querySelectorAll('[data-i18n]');
|
||||
i = elems.length;
|
||||
while ( i-- ) {
|
||||
fillin(elems[i]);
|
||||
}
|
||||
uDom('[data-i18n]').forEach(fillin);
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var getStats = function(request, callback) {
|
||||
var getStats = function(request) {
|
||||
var µb = µBlock;
|
||||
var r = {
|
||||
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
||||
|
@ -39,7 +39,8 @@ var getStats = function(request, callback) {
|
|||
pageBlockedRequestCount: 0,
|
||||
pageAllowedRequestCount: 0,
|
||||
netFilteringSwitch: false,
|
||||
cosmeticFilteringSwitch: false
|
||||
cosmeticFilteringSwitch: false,
|
||||
logBlockedRequests: µb.userSettings.logBlockedRequests
|
||||
};
|
||||
var pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||
if ( pageStore ) {
|
||||
|
@ -157,7 +158,7 @@ var onMessage = function(request, sender, callback) {
|
|||
response = {
|
||||
collapse: µBlock.userSettings.collapseBlocked,
|
||||
blockedRequests: pageStore ? pageStore.blockedRequests : {}
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
// Check a single request
|
||||
|
@ -165,7 +166,7 @@ var onMessage = function(request, sender, callback) {
|
|||
response = {
|
||||
collapse: µBlock.userSettings.collapseBlocked,
|
||||
blocked: pageStore && pageStore.blockedRequests[request.url]
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -253,6 +254,78 @@ var onMessage = function(request, sender, callback) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// stats.js
|
||||
|
||||
(function() {
|
||||
|
||||
var getPageDetails = function(µb, tabId) {
|
||||
var r = {
|
||||
requests: [],
|
||||
hash: ''
|
||||
};
|
||||
var pageStore = µb.pageStores[tabId];
|
||||
if ( !pageStore ) {
|
||||
return r;
|
||||
}
|
||||
var blockedRequests = pageStore.blockedRequests;
|
||||
var details, pos;
|
||||
var hasher = new YaMD5();
|
||||
for ( var requestURL in blockedRequests ) {
|
||||
if ( blockedRequests.hasOwnProperty(requestURL) === false ) {
|
||||
continue;
|
||||
}
|
||||
details = blockedRequests[requestURL];
|
||||
if ( typeof details !== 'string' ) {
|
||||
continue;
|
||||
}
|
||||
hasher.appendStr(requestURL);
|
||||
hasher.appendStr(details);
|
||||
pos = details.indexOf('\t');
|
||||
r.requests.push({
|
||||
type: details.slice(0, pos),
|
||||
domain: µb.URI.domainFromURI(requestURL),
|
||||
url: requestURL,
|
||||
reason: details.slice(pos + 1)
|
||||
});
|
||||
}
|
||||
r.hash = hasher.end();
|
||||
return r;
|
||||
};
|
||||
|
||||
var onMessage = function(request, sender, callback) {
|
||||
var µb = µBlock;
|
||||
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Sync
|
||||
var response;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'getPageSelectors':
|
||||
response = Object.keys(µb.pageStores);
|
||||
break;
|
||||
|
||||
case 'getPageDetails':
|
||||
response = getPageDetails(µb, request.tabId);
|
||||
break;
|
||||
|
||||
default:
|
||||
return µb.messaging.defaultHandler(request, sender, callback);
|
||||
}
|
||||
|
||||
callback(response);
|
||||
};
|
||||
|
||||
µBlock.messaging.listen('stats.js', onMessage);
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// about.js
|
||||
|
||||
(function() {
|
||||
|
|
|
@ -95,13 +95,13 @@ PageStore.prototype.dispose = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
PageStore.prototype.recordRequest = function(type, url, block) {
|
||||
PageStore.prototype.recordRequest = function(type, url, reason) {
|
||||
// rhill 2013-10-26: This needs to be called even if the request is
|
||||
// already logged, since the request stats are cached for a while after
|
||||
// the page is no longer visible in a browser tab.
|
||||
µb.updateBadge(this.tabId);
|
||||
|
||||
if ( block === false ) {
|
||||
if ( reason === false ) {
|
||||
this.perLoadAllowedRequestCount++;
|
||||
µb.localSettings.allowedRequestCount++;
|
||||
return;
|
||||
|
@ -112,7 +112,9 @@ PageStore.prototype.recordRequest = function(type, url, block) {
|
|||
|
||||
// https://github.com/gorhill/uBlock/issues/7
|
||||
// https://github.com/gorhill/uBlock/issues/12
|
||||
this.blockedRequests[url] = true;
|
||||
this.blockedRequests[url] = µb.userSettings.logBlockedRequests ?
|
||||
type + '\t' + reason :
|
||||
true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -120,7 +122,7 @@ PageStore.prototype.recordRequest = function(type, url, block) {
|
|||
// Update badge, incrementally
|
||||
|
||||
// rhill 2013-11-09: well this sucks, I can't update icon/badge
|
||||
// incrementally, as chromium overwrite the icon at some point without
|
||||
// incrementally, as chromium overwrites the icon at some point without
|
||||
// notifying me, and this causes internal cached state to be out of sync.
|
||||
|
||||
PageStore.prototype.updateBadge = function() {
|
||||
|
|
83
js/popup.js
83
js/popup.js
|
@ -24,12 +24,10 @@
|
|||
|
||||
(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var stats;
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/httpswitchboard/issues/345
|
||||
|
@ -65,62 +63,44 @@ formatNumber = function(count) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var hasClassName = function(elem, className) {
|
||||
var re = new RegExp('(^| )' + className + '( |$)', 'g');
|
||||
return re.test(elem.className);
|
||||
};
|
||||
|
||||
var toggleClassName = function(elem, className, newState) {
|
||||
var re = new RegExp('(^| )' + className + '( |$)', 'g');
|
||||
var currentState = re.test(elem.className);
|
||||
if ( newState === undefined ) {
|
||||
newState = !currentState;
|
||||
}
|
||||
if ( newState !== currentState ) {
|
||||
if ( newState ) {
|
||||
elem.className += ' ' + className;
|
||||
} else {
|
||||
elem.className = elem.className.replace(re, '').trim();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var renderStats = function() {
|
||||
if ( !stats || !document.getElementById('switch') ) {
|
||||
if ( !stats ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uDom('#gotoLog').toggleClass('enabled', stats.logBlockedRequests);
|
||||
|
||||
var blocked = stats.pageBlockedRequestCount;
|
||||
var total = stats.pageAllowedRequestCount + blocked;
|
||||
var elem = document.getElementById('page-blocked');
|
||||
var html = [];
|
||||
if ( total === 0 ) {
|
||||
elem.innerHTML = '0';
|
||||
html.push('0');
|
||||
} else {
|
||||
elem.innerHTML = [
|
||||
html.push(
|
||||
formatNumber(blocked),
|
||||
'<span class="dim"> or ',
|
||||
(blocked * 100 / total).toFixed(0),
|
||||
'%</span>'
|
||||
].join('');
|
||||
);
|
||||
}
|
||||
uDom('#page-blocked').html(html.join(''));
|
||||
|
||||
blocked = stats.globalBlockedRequestCount;
|
||||
total = stats.globalAllowedRequestCount + blocked;
|
||||
elem = document.getElementById('total-blocked');
|
||||
html = [];
|
||||
if ( total === 0 ) {
|
||||
elem.innerHTML = '0';
|
||||
html.push('0');
|
||||
} else {
|
||||
elem.innerHTML = [
|
||||
html.push(
|
||||
formatNumber(blocked),
|
||||
'<span class="dim"> or ',
|
||||
(blocked * 100 / total).toFixed(0),
|
||||
'%</span>'
|
||||
].join('');
|
||||
);
|
||||
}
|
||||
uDom('#total-blocked').html(html.join(''));
|
||||
|
||||
toggleClassName(
|
||||
document.querySelector('#switch .fa'),
|
||||
uDom('#switch .fa').toggleClass(
|
||||
'off',
|
||||
stats.pageURL === '' || !stats.netFilteringSwitch
|
||||
);
|
||||
|
@ -154,34 +134,53 @@ var handleNetFilteringSwitch = function() {
|
|||
if ( !stats || !stats.pageURL ) {
|
||||
return;
|
||||
}
|
||||
toggleClassName(this, 'off');
|
||||
var off = uDom(this).toggleClass('off').hasClassName('off');
|
||||
messaging.tell({
|
||||
what: 'toggleNetFiltering',
|
||||
hostname: stats.pageHostname,
|
||||
state: !hasClassName(this, 'off'),
|
||||
state: !off,
|
||||
tabId: stats.tabId
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var renderHeader = function() {
|
||||
var hdr = document.getElementById('version');
|
||||
hdr.innerHTML = hdr.innerHTML + 'v' + chrome.runtime.getManifest().version;
|
||||
var gotoDashboard = function() {
|
||||
messaging.tell({
|
||||
what: 'gotoExtensionURL',
|
||||
url: 'dashboard.html'
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var gotoStats = function() {
|
||||
messaging.tell({
|
||||
what: 'gotoExtensionURL',
|
||||
url: 'dashboard.html?tab=stats&which=' + stats.tabId
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var renderHeader = function() {
|
||||
var hdr = uDom('#version');
|
||||
hdr.html(hdr.html() + 'v' + chrome.runtime.getManifest().version);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var installEventHandlers = function() {
|
||||
document.querySelector('#switch .fa').addEventListener('click', handleNetFilteringSwitch);
|
||||
uDom('h1,h2,h3,h4').on('click', gotoDashboard);
|
||||
uDom('#switch .fa').on('click', handleNetFilteringSwitch);
|
||||
uDom('#gotoLog').on('click', gotoStats);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Make menu only when popup html is fully loaded
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
uDom.onLoad(function() {
|
||||
renderHeader();
|
||||
renderStats();
|
||||
installEventHandlers();
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global chrome, $ */
|
||||
/* global messaging, uDom */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
$(function() {
|
||||
uDom.onLoad(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -44,16 +44,16 @@ var changeUserSettings = function(name, value) {
|
|||
// TODO: use data-* to declare simple settings
|
||||
|
||||
var onUserSettingsReceived = function(details) {
|
||||
$('#collapse-blocked')
|
||||
uDom('#collapse-blocked')
|
||||
.attr('checked', details.collapseBlocked === true)
|
||||
.on('change', function(){
|
||||
changeUserSettings('collapseBlocked', $(this).is(':checked'));
|
||||
changeUserSettings('collapseBlocked', this.checked);
|
||||
});
|
||||
|
||||
$('#icon-badge')
|
||||
uDom('#icon-badge')
|
||||
.attr('checked', details.showIconBadge === true)
|
||||
.on('change', function(){
|
||||
changeUserSettings('showIconBadge', $(this).is(':checked'));
|
||||
changeUserSettings('showIconBadge', this.checked);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/*******************************************************************************
|
||||
|
||||
µBlock - a Chromium browser extension to block requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global chrome, uDom, messaging */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
messaging.start('stats.js');
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var logSettingChanged = function() {
|
||||
messaging.tell({
|
||||
what: 'userSettings',
|
||||
name: 'logBlockedRequests',
|
||||
value: this.checked
|
||||
});
|
||||
uDom('#blockedRequests').toggleClass('logEnabled', this.checked);
|
||||
renderPageSelector();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var cachedPageSelectors = {};
|
||||
var cachedPageHash = '';
|
||||
|
||||
var toPrettyTypeNames = {
|
||||
'sub_frame': 'frame',
|
||||
'object': 'plugin',
|
||||
'xmlhttprequest': 'XHR'
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var renderPageDetails = function(tabId) {
|
||||
if ( !cachedPageSelectors[tabId] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var onDataReceived = function(details) {
|
||||
if ( details.hash === cachedPageHash ) {
|
||||
return;
|
||||
}
|
||||
blockedRequests = details.requests || [];
|
||||
blockedRequests.sort(function(a, b) {
|
||||
var r = a.domain.localeCompare(b.domain);
|
||||
if ( r === 0 ) {
|
||||
r = a.reason.localeCompare(b.reason);
|
||||
if ( r === 0 ) {
|
||||
r = a.type.localeCompare(b.type);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
});
|
||||
|
||||
uDom('#tableHeader ~ tr').remove();
|
||||
|
||||
var blockedRequest, requestURL, renderedURL;
|
||||
var html = [];
|
||||
|
||||
for ( var i = 0; i < blockedRequests.length; i++ ) {
|
||||
blockedRequest = blockedRequests[i];
|
||||
requestURL = blockedRequest.url;
|
||||
renderedURL = [];
|
||||
while ( requestURL.length ) {
|
||||
renderedURL.push(requestURL.slice(0, 60));
|
||||
requestURL = requestURL.slice(60);
|
||||
}
|
||||
html.push(
|
||||
'<tr>',
|
||||
'<td>', toPrettyTypeNames[blockedRequest.type] || blockedRequest.type,
|
||||
'<td>', blockedRequest.domain,
|
||||
'<td>', renderedURL.join('\n'),
|
||||
'<td>', blockedRequest.reason
|
||||
);
|
||||
}
|
||||
if ( !html.length ) {
|
||||
html.push(
|
||||
'<tr><td colspan="4">',
|
||||
chrome.i18n.getMessage('logBlockedRequestsEmpty')
|
||||
);
|
||||
}
|
||||
uDom('#tableHeader').insertAfter(html.join(''));
|
||||
cachedPageHash = details.hash;
|
||||
};
|
||||
|
||||
messaging.ask({ what: 'getPageDetails', tabId: tabId }, onDataReceived);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var pageSelectorChanged = function() {
|
||||
renderPageDetails(this.value);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var renderPageSelector = function(targetTabId) {
|
||||
if ( uDom('#logBlockedRequests').prop('checked') !== true ) {
|
||||
return;
|
||||
}
|
||||
var selectedTabId = targetTabId || parseInt(uDom('#pageSelector').val(), 10);
|
||||
var onTabReceived = function(tab) {
|
||||
var html = [
|
||||
'<option value="',
|
||||
tab.id,
|
||||
'">',
|
||||
tab.title
|
||||
];
|
||||
uDom('#pageSelector').append(html.join(''));
|
||||
if ( tab.id === selectedTabId ) {
|
||||
uDom('#pageSelector').val(tab.id);
|
||||
}
|
||||
};
|
||||
var onDataReceived = function(pageSelectors) {
|
||||
uDom('#pageSelector option').remove();
|
||||
cachedPageSelectors = {};
|
||||
pageSelectors.sort().map(function(tabId) {
|
||||
cachedPageSelectors[tabId] = true;
|
||||
});
|
||||
if ( !cachedPageSelectors[selectedTabId] ) {
|
||||
selectedTabId = pageSelectors[0];
|
||||
}
|
||||
for ( var i = 0; i < pageSelectors.length; i++ ) {
|
||||
chrome.tabs.get(parseInt(pageSelectors[i], 10), onTabReceived);
|
||||
}
|
||||
if ( selectedTabId ) {
|
||||
renderPageDetails(selectedTabId);
|
||||
}
|
||||
};
|
||||
messaging.ask({ what: 'getPageSelectors' }, onDataReceived);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onUserSettingsReceived = function(details) {
|
||||
uDom('#logBlockedRequests').prop('checked', details.logBlockedRequests);
|
||||
uDom('#blockedRequests').toggleClass('logEnabled', details.logBlockedRequests);
|
||||
|
||||
var matches = window.location.search.slice(1).match(/(?:^|&)which=(\d+)/);
|
||||
var tabId = matches && matches.length === 2 ? parseInt(matches[1], 10) : 0;
|
||||
renderPageSelector(tabId);
|
||||
|
||||
uDom('#logBlockedRequests').on('change', logSettingChanged);
|
||||
uDom('#refresh').on('click', function() { renderPageSelector(); });
|
||||
uDom('#pageSelector').on('change', pageSelectorChanged);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uDom.onLoad(function() {
|
||||
messaging.ask({ what: 'userSettings' }, onUserSettingsReceived);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
|
@ -58,11 +58,6 @@ var onBeforeRequestHandler = function(details) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Do not block myself from updating assets
|
||||
if ( requestType === 'xmlhttprequest' && requestURL.slice(0, µb.projectServerRoot.length) === µb.projectServerRoot ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestHostname = µburi.hostname;
|
||||
var requestPath = µburi.path;
|
||||
|
||||
|
|
|
@ -0,0 +1,503 @@
|
|||
/*******************************************************************************
|
||||
|
||||
µBlock - a Chromium browser extension to block requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// It's just a silly, minimalist DOM framework: this allows me to not rely
|
||||
// on jQuery. jQuery contains way too much stuff than I need, and as per
|
||||
// Opera rules, I am not allowed to use a cut-down version of jQuery. So
|
||||
// the code here does *only* what I need, and nothing more, and with a lot
|
||||
// of assumption on passed parameters, etc. I grow it on a per-need-basis only.
|
||||
|
||||
var uDom = (function() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var DOMList = function() {
|
||||
this.nodes = [];
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var DOMListFactory = function(selector, context) {
|
||||
var r = new DOMList();
|
||||
if ( typeof selector === 'string' ) {
|
||||
selector = selector.trim();
|
||||
if ( selector.charAt(0) === '<' ) {
|
||||
return addHTMLToList(r, selector);
|
||||
}
|
||||
if ( selector !== '' ) {
|
||||
return addSelectorToList(r, selector, context);
|
||||
}
|
||||
}
|
||||
if ( selector instanceof Node ) {
|
||||
return addNodeToList(r, selector);
|
||||
}
|
||||
if ( selector instanceof NodeList ) {
|
||||
return addNodeListToList(r, selector);
|
||||
}
|
||||
if ( selector instanceof DOMList ) {
|
||||
return addListToList(r, selector);
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMListFactory.onLoad = function(callback) {
|
||||
window.addEventListener('load', callback);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var addNodeToList = function(list, node) {
|
||||
if ( node ) {
|
||||
list.nodes.push(node);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var addNodeListToList = function(list, nodelist) {
|
||||
if ( nodelist ) {
|
||||
var n = nodelist.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
list.nodes.push(nodelist[i]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var addListToList = function(list, other) {
|
||||
list.nodes = list.nodes.concat(other.nodes);
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var addSelectorToList = function(list, selector, context) {
|
||||
var p = context || document;
|
||||
var r = p.querySelectorAll(selector);
|
||||
var i = r.length;
|
||||
while ( i-- ) {
|
||||
list.nodes.push(r[i]);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var pTagOfChildTag = {
|
||||
'tr': 'table',
|
||||
'option': 'select'
|
||||
};
|
||||
|
||||
var addHTMLToList = function(list, html) {
|
||||
var matches = html.match(/^<([a-z]+)/);
|
||||
if ( !matches || matches.length !== 2 ) {
|
||||
return this;
|
||||
}
|
||||
var cTag = matches[1];
|
||||
var pTag = pTagOfChildTag[cTag] || 'div';
|
||||
var p = document.createElement(pTag);
|
||||
p.innerHTML = html;
|
||||
// Find real parent
|
||||
var c = p.querySelector(cTag);
|
||||
p = c.parentNode;
|
||||
while ( p.firstChild ) {
|
||||
list.nodes.push(p.removeChild(p.firstChild));
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.length = function() {
|
||||
return this.nodes.length;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.subset = function(i, l) {
|
||||
var r = new DOMList();
|
||||
var n = l !== undefined ? l : 1;
|
||||
var j = Math.min(i + n, this.nodes.length);
|
||||
if ( i < j ) {
|
||||
r.nodes = this.nodes.slice(i, j)
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.first = function() {
|
||||
return this.subset(0);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.node = function(i) {
|
||||
return this.nodes[i];
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.parent = function() {
|
||||
var r = new DOMList();
|
||||
if ( this.nodes.length ) {
|
||||
addNodeToList(r, this.nodes[0].parentNode)
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.find = function(selector) {
|
||||
var r = new DOMList();
|
||||
var n = this.nodes.length;
|
||||
var nl;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
nl = this.nodes[i].querySelectorAll(selector);
|
||||
addNodeListToList(r, nl)
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.forEach = function(callback) {
|
||||
var n = this.nodes.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
callback.bind(this.nodes[i]).call();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.remove = function() {
|
||||
var n = this.nodes.length;
|
||||
var c, p;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
c = this.nodes[i];
|
||||
if ( p = c.parentNode ) {
|
||||
p.removeChild(c);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.empty = function() {
|
||||
var node;
|
||||
var i = this.nodes.length;
|
||||
while ( i-- ) {
|
||||
node = this.nodes[i];
|
||||
while ( node.firstChild ) {
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.append = function(selector, context) {
|
||||
var p = this.nodes[0];
|
||||
if ( p ) {
|
||||
var c = DOMListFactory(selector, context);
|
||||
var n = c.nodes.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
p.appendChild(c.nodes[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.prepend = function(selector, context) {
|
||||
var p = this.nodes[0];
|
||||
if ( p ) {
|
||||
var c = DOMListFactory(selector, context);
|
||||
var i = c.nodes.length;
|
||||
while ( i-- ) {
|
||||
p.insertBefore(c.nodes[i], p.firstChild);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.appendTo = function(selector, context) {
|
||||
var p = DOMListFactory(selector, context);
|
||||
if ( p.length ) {
|
||||
var n = this.nodes.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
p.nodes[0].appendChild(this.nodes[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.insertAfter = function(selector, context) {
|
||||
if ( this.nodes.length === 0 ) {
|
||||
return this;
|
||||
}
|
||||
var p = this.nodes[0].parentNode;
|
||||
if ( !p ) {
|
||||
return this;
|
||||
}
|
||||
var c = DOMListFactory(selector, context);
|
||||
var n = c.nodes.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
p.appendChild(c.nodes[i]);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.clone = function(notDeep) {
|
||||
var r = new DOMList();
|
||||
var n = this.nodes.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
addNodeToList(r, this.nodes[i].cloneNode(!notDeep));
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.attr = function(attr, value) {
|
||||
var i = this.nodes.length;
|
||||
if ( value === undefined && typeof attr !== 'object' ) {
|
||||
return i ? this.nodes[0].getAttribute(attr) : undefined;
|
||||
}
|
||||
if ( typeof attr === 'object' ) {
|
||||
var attrNames = Object.keys(attr);
|
||||
var node, j, attrName;
|
||||
while ( i-- ) {
|
||||
node = this.nodes[i];
|
||||
j = attrNames.length;
|
||||
while ( j-- ) {
|
||||
attrName = attrNames[j];
|
||||
node.setAttribute(attrName, attr[attrName]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ( i-- ) {
|
||||
this.nodes[i].setAttribute(attr, value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.prop = function(prop, value) {
|
||||
var i = this.nodes.length;
|
||||
if ( value === undefined ) {
|
||||
return i ? this.nodes[0][prop] : undefined;
|
||||
}
|
||||
while ( i-- ) {
|
||||
this.nodes[i][prop] = value;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.css = function(prop, value) {
|
||||
var i = this.nodes.length;
|
||||
if ( value === undefined ) {
|
||||
return i ? this.nodes[0].style[prop] : undefined;
|
||||
}
|
||||
while ( i-- ) {
|
||||
this.nodes[i].style[prop] = value;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.val = function(value) {
|
||||
return this.prop('value', value);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.html = function(html) {
|
||||
var i = this.nodes.length;
|
||||
if ( html === undefined ) {
|
||||
return i ? this.nodes[0].innerHTML : '';
|
||||
}
|
||||
while ( i-- ) {
|
||||
this.nodes[i].innerHTML = html;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.text = function(text) {
|
||||
var i = this.nodes.length;
|
||||
if ( text === undefined ) {
|
||||
return i ? this.nodes[0].textContent : '';
|
||||
}
|
||||
while ( i-- ) {
|
||||
this.nodes[i].textContent = text;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.hasClassName = function(className) {
|
||||
if ( !this.nodes.length ) {
|
||||
return false;
|
||||
}
|
||||
var re = new RegExp('(^| )' + className + '( |$)');
|
||||
return re.test(this.nodes[0].className);
|
||||
};
|
||||
|
||||
DOMList.prototype.addClass = function(className) {
|
||||
var re = new RegExp('(^| )' + className + '( |$)');
|
||||
var i = this.nodes.length;
|
||||
var before, after;
|
||||
while ( i-- ) {
|
||||
before = this.nodes[i].className;
|
||||
if ( !re.test(before) ) {
|
||||
after = before + ' ' + className;
|
||||
this.nodes[i].className = after.trim();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
DOMList.prototype.removeClass = function() {
|
||||
var i = this.nodes.length;
|
||||
while ( i-- ) {
|
||||
this.nodes[i].className = '';
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
DOMList.prototype.toggleClass = function(className, targetState) {
|
||||
var re = new RegExp('(^| )' + className + '( |$)');
|
||||
var n = this.nodes.length;
|
||||
var node, currentState, newState, newClassName;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
node = this.nodes[i];
|
||||
currentState = re.test(node.className);
|
||||
newState = targetState;
|
||||
if ( newState === undefined ) {
|
||||
newState = !currentState;
|
||||
}
|
||||
if ( newState === currentState ) {
|
||||
continue;
|
||||
}
|
||||
newClassName = node.className;
|
||||
if ( newState ) {
|
||||
newClassName += ' ' + className;
|
||||
} else {
|
||||
newClassName = newClassName.replace(re, '');
|
||||
}
|
||||
node.className = newClassName.trim();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var makeEventHandler = function(context, selector, callback) {
|
||||
return function(event) {
|
||||
var candidates = context.querySelectorAll(selector);
|
||||
if ( !candidates.length ) {
|
||||
return;
|
||||
}
|
||||
var node = event.target;
|
||||
var i;
|
||||
while ( node && node !== context ) {
|
||||
i = candidates.length;
|
||||
while ( i-- ) {
|
||||
if ( candidates[i] === node ) {
|
||||
return callback.bind(node).call(event);
|
||||
}
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
DOMList.prototype.on = function(etype, selector, callback) {
|
||||
if ( typeof selector === 'function' ) {
|
||||
callback = selector;
|
||||
selector = undefined;
|
||||
}
|
||||
var i = this.nodes.length;
|
||||
while ( i-- ) {
|
||||
if ( selector !== undefined ) {
|
||||
this.nodes[i].addEventListener(etype, makeEventHandler(this.nodes[i], selector, callback), true);
|
||||
} else {
|
||||
this.nodes[i].addEventListener(etype, callback);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// TODO: Won't work for delegated handlers. Need to figure
|
||||
// what needs to be done.
|
||||
|
||||
DOMList.prototype.off = function(evtype, callback) {
|
||||
var i = this.nodes.length;
|
||||
while ( i-- ) {
|
||||
this.nodes[i].removeEventListener(evtype, callback);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
DOMList.prototype.trigger = function(etype) {
|
||||
var ev = new CustomEvent(etype);
|
||||
var i = this.nodes.length;
|
||||
while ( i-- ) {
|
||||
this.nodes[i].dispatchEvent(ev);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
return DOMListFactory;
|
||||
|
||||
})();
|
21
js/utils.js
21
js/utils.js
|
@ -40,10 +40,18 @@ var gotoURL = function(details) {
|
|||
/******************************************************************************/
|
||||
|
||||
var gotoExtensionURL = function(url) {
|
||||
var hasFragment = function(url) {
|
||||
return url.indexOf('#') >= 0;
|
||||
|
||||
var hasQuery = function(url) {
|
||||
return url.indexOf('?') >= 0;
|
||||
};
|
||||
|
||||
var removeQuery = function(url) {
|
||||
var pos = url.indexOf('?');
|
||||
if ( pos < 0 ) {
|
||||
return url;
|
||||
}
|
||||
return url.slice(0, pos);
|
||||
};
|
||||
var removeFragment = function(url) {
|
||||
var pos = url.indexOf('#');
|
||||
if ( pos < 0 ) {
|
||||
|
@ -54,26 +62,19 @@ var gotoExtensionURL = function(url) {
|
|||
|
||||
var tabIndex = 9999;
|
||||
var targetUrl = chrome.extension.getURL(url);
|
||||
var urlToFind = removeFragment(targetUrl);
|
||||
|
||||
var currentWindow = function(tabs) {
|
||||
var updateProperties = { active: true };
|
||||
var i = tabs.length;
|
||||
while ( i-- ) {
|
||||
if ( removeFragment(tabs[i].url) !== urlToFind ) {
|
||||
if ( removeQuery(tabs[i].url) !== removeQuery(targetUrl) ) {
|
||||
continue;
|
||||
}
|
||||
// If current tab in dashboard is different, force the new one, if
|
||||
// there is one, to be activated.
|
||||
if ( tabs[i].url !== targetUrl ) {
|
||||
if ( hasFragment(targetUrl) ) {
|
||||
updateProperties.url = targetUrl;
|
||||
}
|
||||
}
|
||||
// Activate found matching tab
|
||||
// Commented out as per:
|
||||
// https://github.com/gorhill/httpswitchboard/issues/150#issuecomment-32683726
|
||||
// chrome.tabs.move(tabs[0].id, { index: index + 1 });
|
||||
chrome.tabs.update(tabs[i].id, updateProperties);
|
||||
return;
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
32
popup.html
32
popup.html
|
@ -19,6 +19,7 @@ h1,h2,h3,h4 {
|
|||
color: white;
|
||||
background-color: #444;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
|
@ -40,6 +41,17 @@ p {
|
|||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
#switch .fa {
|
||||
font-size: 64px;
|
||||
color: green;
|
||||
cursor: pointer;
|
||||
}
|
||||
#switch .fa:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
#switch .fa.off {
|
||||
color: #ccc;
|
||||
}
|
||||
#switch-hint {
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
|
@ -56,16 +68,17 @@ p {
|
|||
margin-bottom: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
#switch .fa {
|
||||
font-size: 64px;
|
||||
color: green;
|
||||
#gotoLog {
|
||||
display: none;
|
||||
font-size: 14px;
|
||||
color: gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
#switch .fa:hover {
|
||||
opacity: 0.9;
|
||||
#gotoLog.hover {
|
||||
color: #444;
|
||||
}
|
||||
#switch .fa.off {
|
||||
color: #ccc;
|
||||
#gotoLog.enabled {
|
||||
display: inline;
|
||||
}
|
||||
#options {
|
||||
margin: 16px 0 0 0;
|
||||
|
@ -80,17 +93,18 @@ p {
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<h4><a href="dashboard.html" target="_blank" title="Click to open the dashboard">µBlock<span id="version"></span></a></h4>
|
||||
<h4 title="Click to open the dashboard">µBlock<span id="version"></span></h4>
|
||||
<div>
|
||||
<p id="switch"><span class="fa"></span></p>
|
||||
<p id="switch-hint" data-i18n="popupPowerSwitchInfo"></p>
|
||||
<p style="font-size: 16px;" data-i18n="popupBlockedRequestPrompt"></p>
|
||||
<p id="stats" data-i18n="popupBlockedOnThisPagePrompt"></p>
|
||||
<p id="stats"><span data-i18n="popupBlockedOnThisPagePrompt"></span> <span id="gotoLog" class="fa"></span></p>
|
||||
<p id="page-blocked">?</p>
|
||||
<p id="stats" data-i18n="popupBlockedSinceInstallPrompt"></p>
|
||||
<p id="total-blocked">?</p>
|
||||
</div>
|
||||
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
<script src="js/popup.js"></script>
|
||||
|
|
|
@ -19,7 +19,7 @@ ul {
|
|||
<li><input id="icon-badge" type="checkbox"> <span data-i18n="settingsIconBadgePrompt"></span>
|
||||
</ul>
|
||||
|
||||
<script src="lib/jquery-2.min.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard-common.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>µBlock — Statistics</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/common.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
|
||||
<style>
|
||||
div {
|
||||
margin: 1em 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
#refresh {
|
||||
margin: 0 0.5em 0 4px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-size: 2em;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
select {
|
||||
padding: 2px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border: 1px solid gray;
|
||||
font: 12px mono;
|
||||
border-collapse: collapse;
|
||||
min-width: 600px;
|
||||
}
|
||||
td, th {
|
||||
border: 1px solid #aaa;
|
||||
padding: 6px 6px;
|
||||
white-space: pre;
|
||||
}
|
||||
td:nth-of-type(2) {
|
||||
text-align: right;
|
||||
}
|
||||
#blockedRequests {
|
||||
margin: 2em 0 0 0;
|
||||
display: none;
|
||||
}
|
||||
#blockedRequests.logEnabled {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<ul>
|
||||
<li><input id="logBlockedRequests" type="checkbox" data-range="bool" /><span data-i18n="logBlockedRequestsPrompt"></span>
|
||||
<button class="whatisthis"></button>
|
||||
<div class="whatisthis-expandable para" data-i18n="logBlockedRequestsHelp"></div>
|
||||
</ul>
|
||||
|
||||
<div id="blockedRequests">
|
||||
<span id="refresh" class="fa"></span><select id="pageSelector"></select>
|
||||
|
||||
<table id="pageDetails">
|
||||
<tr id="tableHeader"><th>Type<th>Domain<th>Blocked URL<th>Filter
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/dashboard-common.js"></script>
|
||||
<script src="js/messaging-client.js"></script>
|
||||
<script src="js/stats.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue