mirror of https://github.com/gorhill/uBlock.git
parent
be27b7aa55
commit
fb62bbc29e
|
@ -2,7 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<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/common.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
|
<link rel="stylesheet" type="text/css" href="css/dashboard-common.css">
|
||||||
<style>
|
<style>
|
||||||
|
@ -33,7 +33,7 @@ div > p:last-child {
|
||||||
<p><button id="userFiltersApply" disabled="true" data-i18n="1pApplyChanges"></button></p>
|
<p><button id="userFiltersApply" disabled="true" data-i18n="1pApplyChanges"></button></p>
|
||||||
</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/i18n.js"></script>
|
||||||
<script src="js/dashboard-common.js"></script>
|
<script src="js/dashboard-common.js"></script>
|
||||||
<script src="js/messaging-client.js"></script>
|
<script src="js/messaging-client.js"></script>
|
||||||
|
|
|
@ -33,7 +33,7 @@ ul > li {
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<p id="3pListsOfBlockedHostsPrompt2"></p>
|
<p id="listsOfBlockedHostsPrompt"></p>
|
||||||
<ul id="blacklistTemplate" style="display:none">
|
<ul id="blacklistTemplate" style="display:none">
|
||||||
<li class="blacklistDetails"><input type="checkbox"> <a href="" type="text/plain"></a>:
|
<li class="blacklistDetails"><input type="checkbox"> <a href="" type="text/plain"></a>:
|
||||||
<span class="dim"></span>
|
<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>
|
<li style="margin-top:0.75em"><button id="blacklistsApply" disabled="true" data-i18n="3pApplyChanges"></button>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script src="lib/jquery-2.min.js"></script>
|
<script src="js/udom.js"></script>
|
||||||
<script src="js/i18n.js"></script>
|
<script src="js/i18n.js"></script>
|
||||||
<script src="js/dashboard-common.js"></script>
|
<script src="js/dashboard-common.js"></script>
|
||||||
<script src="js/messaging-client.js"></script>
|
<script src="js/messaging-client.js"></script>
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "Deine Filter",
|
"message": "Deine Filter",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistics",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "Über",
|
"message": "Über",
|
||||||
"description": "appears as tab name in dashboard"
|
"description": "appears as tab name in dashboard"
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "{{ubiquitousBlacklistCount}} eindeutig blockierte Hostnamen aus:",
|
"message": "{{ubiquitousBlacklistCount}} eindeutig blockierte Hostnamen aus:",
|
||||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
"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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Changelog'>Changelog</a>",
|
"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>"
|
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "Your filters",
|
"message": "Your filters",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistics",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "About",
|
"message": "About",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "{{ubiquitousBlacklistCount}} network filters from:",
|
"message": "{{ubiquitousBlacklistCount}} network filters from:",
|
||||||
"description": "English: {{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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>",
|
"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>"
|
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "Vos règles",
|
"message": "Vos règles",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistiques",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "À propos",
|
"message": "À propos",
|
||||||
"description": "appears as tab name in dashboard"
|
"description": "appears as tab name in dashboard"
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "{{ubiquitousBlacklistCount}} filtres actuellement en action :",
|
"message": "{{ubiquitousBlacklistCount}} filtres actuellement en action :",
|
||||||
"description": "English: {{ubiquitousBlacklistCount}} network filters from:"
|
"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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Journal des changements (en Anglais)</a>",
|
"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>"
|
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "I tuoi filtri",
|
"message": "I tuoi filtri",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistics",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "Info",
|
"message": "Info",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "{{ubiquitousBlacklistCount}} reti filtrate da:",
|
"message": "{{ubiquitousBlacklistCount}} reti filtrate da:",
|
||||||
"description": "English: {{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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>",
|
"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>"
|
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "Your filters",
|
"message": "Your filters",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistics",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "О расширении",
|
"message": "О расширении",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "{{ubiquitousBlacklistCount}} блокируется хостов, помимо:",
|
"message": "{{ubiquitousBlacklistCount}} блокируется хостов, помимо:",
|
||||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
"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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>Список изменений</a>",
|
"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>"
|
"description": "English: <a href='https://github.com/gorhill/ublock/wiki/Change-log'>Change log</a>"
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
"message": "Your filters",
|
"message": "Your filters",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
},
|
},
|
||||||
|
"statsPageName" : {
|
||||||
|
"message": "Statistics",
|
||||||
|
"description": "appears as tab name in dashboard."
|
||||||
|
},
|
||||||
"aboutPageName": {
|
"aboutPageName": {
|
||||||
"message": "关于",
|
"message": "关于",
|
||||||
"description": "appears as tab name in dashboard."
|
"description": "appears as tab name in dashboard."
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"3pListsOfBlockedHostsPrompt2" : {
|
"3pListsOfBlockedHostsPrompt" : {
|
||||||
"message": "共{{ubiquitousBlacklistCount}}个不同的屏蔽站点名,来自:",
|
"message": "共{{ubiquitousBlacklistCount}}个不同的屏蔽站点名,来自:",
|
||||||
"description": "English: {{ubiquitousBlacklistCount}} distinct blocked hostnames from:"
|
"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" : {
|
"aboutChangelog" : {
|
||||||
"message": "<a href='https://github.com/gorhill/ublock/wiki/Change-log'>变更日志</a>",
|
"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>"
|
"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>
|
||||||
</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/i18n.js"></script>
|
||||||
<script src="js/dashboard-common.js"></script>
|
<script src="js/dashboard-common.js"></script>
|
||||||
<script src="js/messaging-client.js"></script>
|
<script src="js/messaging-client.js"></script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 0.5em 5em 0.5em;
|
padding: 0 0.5em 5em 0.5em;
|
||||||
font: 15px sans-serif;
|
font: 14px sans-serif;
|
||||||
}
|
}
|
||||||
h2, h3 {
|
h2, h3 {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
|
|
|
@ -27,7 +27,7 @@ body {
|
||||||
#dashboard-nav-widgets {
|
#dashboard-nav-widgets {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
padding: 4px 0 3px 0;
|
padding: 4px 0 4px 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
@ -76,16 +76,17 @@ iframe {
|
||||||
<div id="dashboard-nav">
|
<div id="dashboard-nav">
|
||||||
<div id="dashboard-nav-widgets">
|
<div id="dashboard-nav-widgets">
|
||||||
<span>µBlock</span>
|
<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" href="#" 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" href="#" 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" href="#" 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="stats.html" data-i18n="statsPageName"></a>
|
||||||
|
<a class="tabButton" href="#" data-dashboard-panel-url="about.html" data-i18n="aboutPageName"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<iframe src=""></iframe>
|
<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/i18n.js"></script>
|
||||||
<script src="js/dashboard.js"></script>
|
<script src="js/dashboard.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global chrome, $ */
|
/* global chrome, messaging, uDom */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -37,12 +37,11 @@ messaging.start('1p-filters.js');
|
||||||
|
|
||||||
// This is to give a visual hint that the content of user blacklist has changed.
|
// This is to give a visual hint that the content of user blacklist has changed.
|
||||||
|
|
||||||
function userFiltersChanged() {
|
function userFiltersChanged(ev) {
|
||||||
$('#userFiltersApply')
|
uDom('#userFiltersApply').prop(
|
||||||
.attr(
|
'disabled',
|
||||||
'disabled',
|
uDom('#userFilters').val().trim() === cachedUserFilters
|
||||||
$('#userFilters').val().trim() === cachedUserFilters
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -53,7 +52,7 @@ function renderUserFilters() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cachedUserFilters = details.content.trim();
|
cachedUserFilters = details.content.trim();
|
||||||
$('#userFilters').val(details.content);
|
uDom('#userFilters').val(details.content);
|
||||||
};
|
};
|
||||||
messaging.ask({ what: 'readUserFilters' }, onRead);
|
messaging.ask({ what: 'readUserFilters' }, onRead);
|
||||||
}
|
}
|
||||||
|
@ -62,23 +61,22 @@ function renderUserFilters() {
|
||||||
|
|
||||||
function allFiltersApplyHandler() {
|
function allFiltersApplyHandler() {
|
||||||
messaging.tell({ what: 'reloadAllFilters' });
|
messaging.tell({ what: 'reloadAllFilters' });
|
||||||
$('#userFiltersApply').attr('disabled', true );
|
uDom('#userFiltersApply').prop('disabled', true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
function appendToUserFiltersFromFile() {
|
function appendToUserFiltersFromFile() {
|
||||||
var input = $('<input />').attr({
|
var input = uDom('<input />').attr({
|
||||||
type: 'file',
|
type: 'file',
|
||||||
accept: 'text/plain'
|
accept: 'text/plain'
|
||||||
});
|
});
|
||||||
var fileReaderOnLoadHandler = function() {
|
var fileReaderOnLoadHandler = function() {
|
||||||
var textarea = $('#userFilters');
|
var textarea = uDom('#userFilters');
|
||||||
textarea.val(textarea.val() + '\n' + this.result);
|
textarea.val([textarea.val(), this.result].join('\n').trim());
|
||||||
userFiltersChanged();
|
userFiltersChanged();
|
||||||
};
|
};
|
||||||
var filePickerOnChangeHandler = function() {
|
var filePickerOnChangeHandler = function() {
|
||||||
$(this).off('change', filePickerOnChangeHandler);
|
|
||||||
var file = this.files[0];
|
var file = this.files[0];
|
||||||
if ( !file ) {
|
if ( !file ) {
|
||||||
return;
|
return;
|
||||||
|
@ -99,7 +97,7 @@ function appendToUserFiltersFromFile() {
|
||||||
|
|
||||||
function exportUserFiltersToFile() {
|
function exportUserFiltersToFile() {
|
||||||
chrome.downloads.download({
|
chrome.downloads.download({
|
||||||
'url': 'data:text/plain,' + encodeURIComponent($('#userFilters').val()),
|
'url': 'data:text/plain,' + encodeURIComponent(uDom('#userFilters').val()),
|
||||||
'filename': 'my-ublock-filters.txt',
|
'filename': 'my-ublock-filters.txt',
|
||||||
'saveAs': true
|
'saveAs': true
|
||||||
});
|
});
|
||||||
|
@ -118,19 +116,19 @@ function userFiltersApplyHandler() {
|
||||||
};
|
};
|
||||||
var request = {
|
var request = {
|
||||||
what: 'writeUserFilters',
|
what: 'writeUserFilters',
|
||||||
content: $('#userFilters').val()
|
content: uDom('#userFilters').val()
|
||||||
};
|
};
|
||||||
messaging.ask(request, onWritten);
|
messaging.ask(request, onWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
$(function() {
|
uDom.onLoad(function() {
|
||||||
// Handle user interaction
|
// Handle user interaction
|
||||||
$('#importUserFiltersFromFile').on('click', appendToUserFiltersFromFile);
|
uDom('#importUserFiltersFromFile').on('click', appendToUserFiltersFromFile);
|
||||||
$('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
|
uDom('#exportUserFiltersToFile').on('click', exportUserFiltersToFile);
|
||||||
$('#userFilters').on('input propertychange', userFiltersChanged);
|
uDom('#userFilters').on('input', userFiltersChanged);
|
||||||
$('#userFiltersApply').on('click', userFiltersApplyHandler);
|
uDom('#userFiltersApply').on('click', userFiltersApplyHandler);
|
||||||
|
|
||||||
renderUserFilters();
|
renderUserFilters();
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global chrome, $ */
|
/* global chrome, messaging, uDom */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var userListName = chrome.i18n.getMessage('1pPageName');
|
var userListName = chrome.i18n.getMessage('1pPageName');
|
||||||
var cachedUserUbiquitousBlacklistedHosts = '';
|
|
||||||
var cachedUserUbiquitousWhitelistedHosts = '';
|
|
||||||
var selectedBlacklistsHash = '';
|
var selectedBlacklistsHash = '';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -77,12 +75,12 @@ function renderNumber(value) {
|
||||||
|
|
||||||
function renderBlacklists() {
|
function renderBlacklists() {
|
||||||
// empty list first
|
// empty list first
|
||||||
$('#blacklists .blacklistDetails').remove();
|
uDom('#blacklists .blacklistDetails').remove();
|
||||||
|
|
||||||
var µb = getµb();
|
var µb = getµb();
|
||||||
|
|
||||||
$('#3pListsOfBlockedHostsPrompt2').text(
|
uDom('#listsOfBlockedHostsPrompt').text(
|
||||||
chrome.i18n.getMessage('3pListsOfBlockedHostsPrompt2')
|
chrome.i18n.getMessage('3pListsOfBlockedHostsPrompt')
|
||||||
.replace('{{ubiquitousBlacklistCount}}', renderNumber(µb.abpFilters.getFilterCount()))
|
.replace('{{ubiquitousBlacklistCount}}', renderNumber(µb.abpFilters.getFilterCount()))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -119,31 +117,29 @@ function renderBlacklists() {
|
||||||
|
|
||||||
var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats');
|
var listStatsTemplate = chrome.i18n.getMessage('3pListsOfBlockedHostsPerListStats');
|
||||||
var blacklists = µb.remoteBlacklists;
|
var blacklists = µb.remoteBlacklists;
|
||||||
var ul = $('#blacklists');
|
var ul = uDom('#blacklists');
|
||||||
var keys = Object.keys(blacklists);
|
var keys = Object.keys(blacklists);
|
||||||
var i = keys.length;
|
var i = keys.length;
|
||||||
var blacklist, blacklistHref;
|
var blacklist, blacklistHref;
|
||||||
var liTemplate = $('#blacklistTemplate .blacklistDetails').first();
|
var liTemplate = uDom('#blacklistTemplate .blacklistDetails').first();
|
||||||
var li, child, text;
|
var li, text;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
blacklistHref = keys[i];
|
blacklistHref = keys[i];
|
||||||
blacklist = blacklists[blacklistHref];
|
blacklist = blacklists[blacklistHref];
|
||||||
li = liTemplate.clone();
|
li = liTemplate.clone();
|
||||||
child = $('input', li);
|
li.find('input').prop('checked', !blacklist.off);
|
||||||
child.prop('checked', !blacklist.off);
|
li.find('a')
|
||||||
child = $('a', li);
|
.attr('href', encodeURI(blacklistHref))
|
||||||
child.attr('href', encodeURI(blacklistHref));
|
.html(prettifyListName(blacklist.title, blacklistHref));
|
||||||
child.html(prettifyListName(blacklist.title, blacklistHref));
|
|
||||||
child = $('span', li);
|
|
||||||
text = listStatsTemplate
|
text = listStatsTemplate
|
||||||
.replace('{{used}}', !blacklist.off && !isNaN(+blacklist.entryUsedCount) ? renderNumber(blacklist.entryUsedCount) : '0')
|
.replace('{{used}}', !blacklist.off && !isNaN(+blacklist.entryUsedCount) ? renderNumber(blacklist.entryUsedCount) : '0')
|
||||||
.replace('{{total}}', !isNaN(+blacklist.entryCount) ? renderNumber(blacklist.entryCount) : '?')
|
.replace('{{total}}', !isNaN(+blacklist.entryCount) ? renderNumber(blacklist.entryCount) : '?')
|
||||||
;
|
;
|
||||||
child.text(text);
|
li.find('span').text(text);
|
||||||
ul.prepend(li);
|
ul.prepend(li);
|
||||||
}
|
}
|
||||||
$('#parseAllABPHideFilters').attr('checked', µb.userSettings.parseAllABPHideFilters === true);
|
uDom('#parseAllABPHideFilters').attr('checked', µb.userSettings.parseAllABPHideFilters === true);
|
||||||
$('#ubiquitousParseAllABPHideFiltersPrompt2').text(
|
uDom('#ubiquitousParseAllABPHideFiltersPrompt2').text(
|
||||||
chrome.i18n.getMessage("listsParseAllABPHideFiltersPrompt2")
|
chrome.i18n.getMessage("listsParseAllABPHideFiltersPrompt2")
|
||||||
.replace('{{abpHideFilterCount}}', renderNumber(µb.abpHideFilters.getFilterCount()))
|
.replace('{{abpHideFilterCount}}', renderNumber(µb.abpHideFilters.getFilterCount()))
|
||||||
);
|
);
|
||||||
|
@ -158,15 +154,13 @@ function renderBlacklists() {
|
||||||
|
|
||||||
function getSelectedBlacklistsHash() {
|
function getSelectedBlacklistsHash() {
|
||||||
var hash = '';
|
var hash = '';
|
||||||
var inputs = $('#blacklists .blacklistDetails > input');
|
var inputs = uDom('#blacklists .blacklistDetails > input');
|
||||||
var i = inputs.length;
|
var i = inputs.length();
|
||||||
var entryHash;
|
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
entryHash = $(inputs[i]).prop('checked').toString();
|
hash += inputs.subset(i).prop('checked').toString();
|
||||||
hash += entryHash;
|
|
||||||
}
|
}
|
||||||
// Factor in whether ABP filters are to be processed
|
// Factor in whether cosmetic filters are to be processed
|
||||||
hash += $('#parseAllABPHideFilters').prop('checked').toString();
|
hash += uDom('#parseAllABPHideFilters').prop('checked').toString();
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +170,7 @@ function getSelectedBlacklistsHash() {
|
||||||
// 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.
|
||||||
|
|
||||||
function selectedBlacklistsChanged() {
|
function selectedBlacklistsChanged() {
|
||||||
$('#blacklistsApply').attr(
|
uDom('#blacklistsApply').prop(
|
||||||
'disabled',
|
'disabled',
|
||||||
getSelectedBlacklistsHash() === selectedBlacklistsHash
|
getSelectedBlacklistsHash() === selectedBlacklistsHash
|
||||||
);
|
);
|
||||||
|
@ -191,21 +185,21 @@ function blacklistsApplyHandler() {
|
||||||
}
|
}
|
||||||
// Reload blacklists
|
// Reload blacklists
|
||||||
var switches = [];
|
var switches = [];
|
||||||
var lis = $('#blacklists .blacklistDetails');
|
var lis = uDom('#blacklists .blacklistDetails');
|
||||||
var i = lis.length;
|
var i = lis.length();
|
||||||
var path;
|
var path;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
path = $(lis[i]).children('a').attr('href');
|
path = lis.subset(i).find('a').attr('href');
|
||||||
switches.push({
|
switches.push({
|
||||||
location: path,
|
location: path,
|
||||||
off: $(lis[i]).children('input').prop('checked') === false
|
off: lis.subset(i).find('input').prop('checked') === false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
messaging.tell({
|
messaging.tell({
|
||||||
what: 'reloadAllFilters',
|
what: 'reloadAllFilters',
|
||||||
switches: switches
|
switches: switches
|
||||||
});
|
});
|
||||||
$('#blacklistsApply').attr('disabled', true );
|
uDom('#blacklistsApply').attr('disabled', true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -214,18 +208,18 @@ function abpHideFiltersCheckboxChanged() {
|
||||||
messaging.tell({
|
messaging.tell({
|
||||||
what: 'userSettings',
|
what: 'userSettings',
|
||||||
name: 'parseAllABPHideFilters',
|
name: 'parseAllABPHideFilters',
|
||||||
value: $(this).is(':checked')
|
value: this.checked
|
||||||
});
|
});
|
||||||
selectedBlacklistsChanged();
|
selectedBlacklistsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
uDom.onLoad(function() {
|
||||||
// Handle user interaction
|
// Handle user interaction
|
||||||
$('#blacklists').on('change', '.blacklistDetails', selectedBlacklistsChanged);
|
uDom('#blacklists').on('change', '.blacklistDetails', selectedBlacklistsChanged);
|
||||||
$('#blacklistsApply').on('click', blacklistsApplyHandler);
|
uDom('#blacklistsApply').on('click', blacklistsApplyHandler);
|
||||||
$('#parseAllABPHideFilters').on('change', abpHideFiltersCheckboxChanged);
|
uDom('#parseAllABPHideFilters').on('change', abpHideFiltersCheckboxChanged);
|
||||||
|
|
||||||
renderBlacklists();
|
renderBlacklists();
|
||||||
});
|
});
|
||||||
|
|
36
js/about.js
36
js/about.js
|
@ -19,11 +19,11 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
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) {
|
var setAssetListClassBit = function(bit, state) {
|
||||||
assetListSwitches[assetListSwitches.length-1-bit] = !state ? 'o' : 'x';
|
assetListSwitches[assetListSwitches.length-1-bit] = !state ? 'o' : 'x';
|
||||||
$('#assetList')
|
uDom('#assetList')
|
||||||
.removeClass()
|
.removeClass()
|
||||||
.addClass(assetListSwitches.join(''));
|
.addClass(assetListSwitches.join(''));
|
||||||
};
|
};
|
||||||
|
@ -46,24 +46,24 @@ var renderAssetList = function(details) {
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
var paths = Object.keys(details.list).sort();
|
var paths = Object.keys(details.list).sort();
|
||||||
if ( paths.length > 0 ) {
|
if ( paths.length > 0 ) {
|
||||||
$('#assetList .assetEntry').remove();
|
uDom('#assetList .assetEntry').remove();
|
||||||
var assetTable = $('#assetList table');
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var path, status, html;
|
var path, status, html = [];
|
||||||
while ( path = paths[i++] ) {
|
while ( path = paths[i++] ) {
|
||||||
status = details.list[path].status;
|
status = details.list[path].status;
|
||||||
dirty = dirty || status !== 'Unchanged';
|
dirty = dirty || status !== 'Unchanged';
|
||||||
html = [];
|
html.push(
|
||||||
html.push('<tr class="assetEntry ' + status.toLowerCase().replace(/ +/g, '-') + '">');
|
'<tr class="assetEntry ' + status.toLowerCase().replace(/ +/g, '-') + '">',
|
||||||
html.push('<td>');
|
'<td>',
|
||||||
html.push('<a href="' + commitHistoryURLPrefix + path + '">');
|
'<a href="' + commitHistoryURLPrefix + path + '">',
|
||||||
html.push(path.replace(/^(assets\/[^/]+\/)(.+)$/, '$1<b>$2</b>'));
|
path.replace(/^(assets\/[^/]+\/)(.+)$/, '$1<b>$2</b>'),
|
||||||
html.push('</a>');
|
'</a>',
|
||||||
html.push('<td>');
|
'<td>',
|
||||||
html.push(chrome.i18n.getMessage('aboutAssetsUpdateStatus' + status));
|
chrome.i18n.getMessage('aboutAssetsUpdateStatus' + status)
|
||||||
assetTable.append(html.join(''));
|
);
|
||||||
}
|
}
|
||||||
$('#assetList a').attr('target', '_blank');
|
uDom('#assetList table tBody').append(html.join(''));
|
||||||
|
uDom('#assetList a').attr('target', '_blank');
|
||||||
updateList = details.list;
|
updateList = details.list;
|
||||||
}
|
}
|
||||||
setAssetListClassBit(0, paths.length !== 0);
|
setAssetListClassBit(0, paths.length !== 0);
|
||||||
|
@ -110,8 +110,8 @@ messaging.listen(onAnnounce);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
$('#aboutVersion').html(chrome.runtime.getManifest().version);
|
uDom('#aboutVersion').html(chrome.runtime.getManifest().version);
|
||||||
$('#aboutAssetsUpdateButton').on('click', updateAssets);
|
uDom('#aboutAssetsUpdateButton').on('click', updateAssets);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -600,16 +600,11 @@ FilterContainer.prototype.retrieveGenericSelectors = function(tabHostname, reque
|
||||||
|
|
||||||
//quickProfiler.stop();
|
//quickProfiler.stop();
|
||||||
|
|
||||||
/*
|
//console.log(
|
||||||
console.log(
|
// 'µBlock> abp-hide-filters.js: %d selectors in => %d selectors out',
|
||||||
'µBlock> abp-hide-filters.js: "%s"\n\t%d selectors in => %d/%d filters/buckets tested => %d selectors out',
|
// request.selectors.length,
|
||||||
url,
|
// r.hide.length + r.donthide.length
|
||||||
inSelectors.length,
|
//);
|
||||||
//filterTestCount,
|
|
||||||
//bucketTestCount,
|
|
||||||
hideSelectors.length + donthideSelectors.length
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
@ -656,16 +651,11 @@ FilterContainer.prototype.retrieveDomainSelectors = function(tabHostname, reques
|
||||||
|
|
||||||
//quickProfiler.stop();
|
//quickProfiler.stop();
|
||||||
|
|
||||||
/*
|
//console.log(
|
||||||
console.log(
|
// 'µBlock> abp-hide-filters.js: "%s" => %d selectors out',
|
||||||
'µBlock> abp-hide-filters.js: "%s"\n\t%d selectors in => %d/%d filters/buckets tested => %d selectors out',
|
// request.locationURL,
|
||||||
url,
|
// r.hide.length + r.donthide.length
|
||||||
inSelectors.length,
|
//);
|
||||||
//filterTestCount,
|
|
||||||
//bucketTestCount,
|
|
||||||
hideSelectors.length + donthideSelectors.length
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,7 @@ return {
|
||||||
|
|
||||||
userSettings: {
|
userSettings: {
|
||||||
collapseBlocked: true,
|
collapseBlocked: true,
|
||||||
|
logBlockedRequests: false,
|
||||||
parseAllABPHideFilters: true,
|
parseAllABPHideFilters: true,
|
||||||
netExceptionList: {},
|
netExceptionList: {},
|
||||||
showIconBadge: true
|
showIconBadge: true
|
||||||
|
@ -41,7 +42,7 @@ return {
|
||||||
allowedRequestCount: 0
|
allowedRequestCount: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAssetsEvery: 5 * 24 * 60 * 60 * 1000,
|
updateAssetsEvery: 4 * 24 * 60 * 60 * 1000,
|
||||||
projectServerRoot: 'https://raw2.github.com/gorhill/ublock/master/',
|
projectServerRoot: 'https://raw2.github.com/gorhill/ublock/master/',
|
||||||
userFiltersPath: 'assets/user/filters.txt',
|
userFiltersPath: 'assets/user/filters.txt',
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/345
|
// https://github.com/gorhill/httpswitchboard/issues/345
|
||||||
|
|
||||||
var messaging = (function(name){
|
var messaging = (function(name){
|
||||||
|
@ -121,301 +125,300 @@ var messaging = (function(name){
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// ABP cosmetic filters
|
// ABP cosmetic filters
|
||||||
|
|
||||||
var CosmeticFiltering = function() {
|
var cosmeticFiltering = (function() {
|
||||||
this.queriedSelectors = {};
|
|
||||||
this.injectedSelectors = {};
|
|
||||||
this.classSelectors = null;
|
|
||||||
this.idSelectors = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.onDOMContentLoaded = function() {
|
var queriedSelectors = {};
|
||||||
// https://github.com/gorhill/uBlock/issues/14
|
var injectedSelectors = {};
|
||||||
// Treat any existing domain-specific exception selectors as if they had
|
var classSelectors = null;
|
||||||
// been injected already.
|
var idSelectors = null;
|
||||||
var style = document.getElementById('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5');
|
|
||||||
var exceptions = style && style.getAttribute('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5');
|
var domLoaded = function() {
|
||||||
if ( exceptions ) {
|
// https://github.com/gorhill/uBlock/issues/14
|
||||||
exceptions = decodeURIComponent(exceptions).split('\n');
|
// Treat any existing domain-specific exception selectors as if they had
|
||||||
var i = exceptions.length;
|
// been injected already.
|
||||||
|
var style = document.getElementById('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5');
|
||||||
|
var exceptions = style && style.getAttribute('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5');
|
||||||
|
if ( exceptions ) {
|
||||||
|
exceptions = decodeURIComponent(exceptions).split('\n');
|
||||||
|
var i = exceptions.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
injectedSelectors[exceptions[i]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: evaluate merging into a single loop
|
||||||
|
selectorsFromNodeList(document.querySelectorAll('*[class],*[id]'));
|
||||||
|
retrieveGenericSelectors();
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
messaging.ask({
|
||||||
|
what: 'retrieveGenericCosmeticSelectors',
|
||||||
|
pageURL: window.location.href,
|
||||||
|
selectors: selectors
|
||||||
|
},
|
||||||
|
retrieveHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
idSelectors = null;
|
||||||
|
classSelectors = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
var retrieveHandler = function(selectors) {
|
||||||
|
if ( !selectors ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var styleText = [];
|
||||||
|
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);
|
||||||
|
applyCSS(selectors.hide, 'display', 'none');
|
||||||
|
//console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.hide.length, hideStyleText);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
applyCSS(selectors.donthide, 'display', 'initial');
|
||||||
|
//console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.donthide.length, dontHideStyleText);
|
||||||
|
}
|
||||||
|
if ( styleText.length > 0 ) {
|
||||||
|
var style = document.createElement('style');
|
||||||
|
style.appendChild(document.createTextNode(styleText.join('\n')));
|
||||||
|
var parent = document.body || document.documentElement;
|
||||||
|
if ( parent ) {
|
||||||
|
parent.appendChild(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var applyCSS = function(selectors, prop, value) {
|
||||||
|
if ( document.body === null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var elems = document.querySelectorAll(selectors);
|
||||||
|
var i = elems.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
this.injectedSelectors[exceptions[i]] = true;
|
elems[i].style[prop] = value;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// TODO: evaluate merging into a single loop
|
var filterUnfiltered = function(inSelectors, outSelectors) {
|
||||||
this.classesFromNodeList(document.querySelectorAll('*[class]'));
|
var i = inSelectors.length;
|
||||||
this.idsFromNodeList(document.querySelectorAll('*[id]'));
|
var selector;
|
||||||
this.retrieveGenericSelectors();
|
while ( i-- ) {
|
||||||
};
|
selector = inSelectors[i];
|
||||||
|
if ( injectedSelectors[selector] ) {
|
||||||
CosmeticFiltering.prototype.retrieveGenericSelectors = function() {
|
|
||||||
var selectors = this.classSelectors !== null ? Object.keys(this.classSelectors) : [];
|
|
||||||
if ( this.idSelectors !== null ) {
|
|
||||||
selectors = selectors.concat(this.idSelectors);
|
|
||||||
}
|
|
||||||
if ( selectors.length > 0 ) {
|
|
||||||
//console.log('µBlock> ABP cosmetic filters: retrieving CSS rules using %d selectors', selectors.length);
|
|
||||||
messaging.ask({
|
|
||||||
what: 'retrieveGenericCosmeticSelectors',
|
|
||||||
pageURL: window.location.href,
|
|
||||||
selectors: selectors
|
|
||||||
},
|
|
||||||
this.retrieveHandler.bind(this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.idSelectors = null;
|
|
||||||
this.classSelectors = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.retrieveHandler = function(selectors) {
|
|
||||||
if ( !selectors ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var styleText = [];
|
|
||||||
this.filterUnfiltered(selectors.hideUnfiltered, selectors.hide);
|
|
||||||
this.reduce(selectors.hide, this.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');
|
|
||||||
//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);
|
|
||||||
if ( selectors.donthide.length ) {
|
|
||||||
var dontHideStyleText = '{{donthideSelectors}} {display:initial !important;}'
|
|
||||||
.replace('{{donthideSelectors}}', selectors.donthide.join(','));
|
|
||||||
styleText.push(dontHideStyleText);
|
|
||||||
this.applyCSS(selectors.donthide, 'display', 'initial');
|
|
||||||
//console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.donthide.length, dontHideStyleText);
|
|
||||||
}
|
|
||||||
if ( styleText.length > 0 ) {
|
|
||||||
var style = document.createElement('style');
|
|
||||||
style.appendChild(document.createTextNode(styleText.join('\n')));
|
|
||||||
var parent = document.body || document.documentElement;
|
|
||||||
if ( parent ) {
|
|
||||||
parent.appendChild(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.applyCSS = function(selectors, prop, value) {
|
|
||||||
if ( document.body === null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var elems = document.querySelectorAll(selectors);
|
|
||||||
var i = elems.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
elems[i].style[prop] = value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.filterUnfiltered = function(inSelectors, outSelectors) {
|
|
||||||
var i = inSelectors.length;
|
|
||||||
var selector;
|
|
||||||
while ( i-- ) {
|
|
||||||
selector = inSelectors[i];
|
|
||||||
if ( this.injectedSelectors[selector] ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( document.querySelector(selector) !== null ) {
|
|
||||||
outSelectors.push(selector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.reduce = function(selectors, dict) {
|
|
||||||
var i = selectors.length, selector, end;
|
|
||||||
while ( i-- ) {
|
|
||||||
selector = selectors[i];
|
|
||||||
if ( !dict[selector] ) {
|
|
||||||
if ( end !== undefined ) {
|
|
||||||
selectors.splice(i+1, end-i);
|
|
||||||
end = undefined;
|
|
||||||
}
|
|
||||||
dict[selector] = true;
|
|
||||||
} else if ( end === undefined ) {
|
|
||||||
end = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( end !== undefined ) {
|
|
||||||
selectors.splice(0, end+1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.classesFromNodeList = function(nodes) {
|
|
||||||
if ( !nodes ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( this.classSelectors === null ) {
|
|
||||||
this.classSelectors = {};
|
|
||||||
}
|
|
||||||
var classNames, className, 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;
|
continue;
|
||||||
}
|
}
|
||||||
this.classSelectors[className] = true;
|
if ( document.querySelector(selector) !== null ) {
|
||||||
this.queriedSelectors[className] = true;
|
outSelectors.push(selector);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
classNames = className.trim().split(/\s+/);
|
};
|
||||||
j = classNames.length;
|
|
||||||
while ( j-- ) {
|
var reduce = function(selectors, dict) {
|
||||||
className = classNames[j];
|
var i = selectors.length, selector, end;
|
||||||
if ( className === '' ) {
|
while ( i-- ) {
|
||||||
|
selector = selectors[i];
|
||||||
|
if ( !dict[selector] ) {
|
||||||
|
if ( end !== undefined ) {
|
||||||
|
selectors.splice(i+1, end-i);
|
||||||
|
end = undefined;
|
||||||
|
}
|
||||||
|
dict[selector] = true;
|
||||||
|
} else if ( end === undefined ) {
|
||||||
|
end = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( end !== undefined ) {
|
||||||
|
selectors.splice(0, end+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var selectorsFromNodeList = function(nodes) {
|
||||||
|
if ( !nodes || !nodes.length ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( idSelectors === null ) {
|
||||||
|
idSelectors = [];
|
||||||
|
}
|
||||||
|
if ( classSelectors === null ) {
|
||||||
|
classSelectors = {};
|
||||||
|
}
|
||||||
|
var qq = queriedSelectors;
|
||||||
|
var cc = classSelectors;
|
||||||
|
var ii = idSelectors;
|
||||||
|
var node, v, classNames, j;
|
||||||
|
var i = nodes.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
node = nodes[i];
|
||||||
|
if ( node.nodeType !== 1 ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
className = '.' + className;
|
// id
|
||||||
if ( this.queriedSelectors[className] ) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
this.classSelectors[className] = true;
|
// many classes
|
||||||
this.queriedSelectors[className] = true;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.idsFromNodeList = function(nodes) {
|
var processNodeLists = function(nodeLists) {
|
||||||
if ( !nodes ) {
|
var i = nodeLists.length;
|
||||||
return;
|
var nodeList, j, node;
|
||||||
}
|
while ( i-- ) {
|
||||||
if ( this.idSelectors === null ) {
|
nodeList = nodeLists[i];
|
||||||
this.idSelectors = [];
|
selectorsFromNodeList(nodeList);
|
||||||
}
|
j = nodeList.length;
|
||||||
var id;
|
while ( j-- ) {
|
||||||
var i = nodes.length;
|
node = nodeList[j];
|
||||||
while ( i-- ) {
|
if ( node.querySelectorAll ) {
|
||||||
id = nodes[i].id;
|
selectorsFromNodeList(node.querySelectorAll('*[id],*[class]'));
|
||||||
if ( !id ) {
|
}
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
id = '#' + id;
|
retrieveGenericSelectors();
|
||||||
if ( this.queriedSelectors[id] ) {
|
};
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.idSelectors.push(id);
|
|
||||||
this.queriedSelectors[id] = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CosmeticFiltering.prototype.allFromNodeList = function(nodes) {
|
domLoaded();
|
||||||
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]'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var cosmeticFiltering = new CosmeticFiltering();
|
return {
|
||||||
|
processNodeLists: processNodeLists
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/7
|
// https://github.com/gorhill/uBlock/issues/7
|
||||||
|
|
||||||
var observeElement = function(elem) {
|
var blockedElementHider = (function() {
|
||||||
var onLoad = function() {
|
var hideOne = function(elem, collapse) {
|
||||||
var elem = this;
|
// If `!important` is not there, going back using history will likely
|
||||||
var onAnswerReceived = function(details) {
|
// cause the hidden element to re-appear.
|
||||||
if ( details.blocked ) {
|
elem.style.visibility = 'hidden !important';
|
||||||
hideBlockedElement(elem, details.collapse);
|
if ( collapse && elem.parentNode ) {
|
||||||
|
elem.parentNode.removeChild(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
var elem, src;
|
||||||
|
while ( i-- ) {
|
||||||
|
elem = elems[i];
|
||||||
|
src = elem.src;
|
||||||
|
if ( typeof src !== 'string' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( src === '' ) {
|
||||||
|
observeOne(elem);
|
||||||
|
} else if ( blockedRequests[src] ) {
|
||||||
|
hideOne(elem, collapse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var processElements = function(elems) {
|
||||||
|
var blockedRequestsReceived = function(details) {
|
||||||
|
hideMany(elems, details);
|
||||||
|
var i = elems.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
hideMany(elems[i].querySelectorAll('img,iframe'), details);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
messaging.ask({ what: 'blockedRequest', url: this.src }, onAnswerReceived);
|
messaging.ask({ what: 'blockedRequests' }, blockedRequestsReceived);
|
||||||
this.removeEventListener('load', onLoad);
|
|
||||||
};
|
};
|
||||||
elem.addEventListener('load', onLoad);
|
|
||||||
};
|
|
||||||
|
|
||||||
var hideBlockedElement = function(elem, collapse) {
|
// rhill 2014-07-01: Avoid useless work: only nodes which are element are
|
||||||
// If `!important` is not there, going back using history will likely
|
// of interest at this point -- because it is common that a lot of plain
|
||||||
// cause the hidden element to re-appear.
|
// text nodes get added.
|
||||||
elem.style.visibility = 'hidden !important';
|
var addNodeLists = function(nodeLists) {
|
||||||
if ( collapse && elem.parentNode ) {
|
var elems = [];
|
||||||
elem.parentNode.removeChild(elem);
|
var i = nodeLists.length;
|
||||||
}
|
var nodeList, j, node;
|
||||||
};
|
|
||||||
|
|
||||||
var hideBlockedElements = function(elems, details) {
|
|
||||||
var blockedRequests = details.blockedRequests;
|
|
||||||
var collapse = details.collapse;
|
|
||||||
var i = elems.length;
|
|
||||||
var elem, src;
|
|
||||||
while ( i-- ) {
|
|
||||||
elem = elems[i];
|
|
||||||
src = elem.src;
|
|
||||||
if ( typeof src !== 'string' ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( src === '' ) {
|
|
||||||
observeElement(elem);
|
|
||||||
} else if ( blockedRequests[src] ) {
|
|
||||||
hideBlockedElement(elem, collapse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var hideBlockedElementInAddedNodes = function(nodes) {
|
|
||||||
var onBlockedRequestsReceived = function(details) {
|
|
||||||
hideBlockedElements(nodes, details);
|
|
||||||
var i = nodes.length;
|
|
||||||
var elem;
|
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
elem = nodes[i];
|
nodeList = nodeLists[i];
|
||||||
if ( elem.querySelectorAll ) {
|
j = nodeList.length;
|
||||||
hideBlockedElements(elem.querySelectorAll('img,iframe'), details);
|
while ( j-- ) {
|
||||||
|
node = nodeList[j];
|
||||||
|
if ( node.querySelectorAll ) {
|
||||||
|
elems.push(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
if ( elems.length ) {
|
||||||
messaging.ask({ what: 'blockedRequests' }, onBlockedRequestsReceived);
|
processElements(elems);
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var onBlockedRequestsReceived = function(details) {
|
|
||||||
hideBlockedElements(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();
|
var onBlockedRequestsReceived = function(details) {
|
||||||
};
|
hideMany(document.querySelectorAll('img,iframe'), details);
|
||||||
|
};
|
||||||
|
messaging.ask({ what: 'blockedRequests' }, onBlockedRequestsReceived);
|
||||||
|
|
||||||
|
return {
|
||||||
|
addNodeLists: addNodeLists
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -435,12 +438,23 @@ if ( /^https?:\/\/./.test(window.location.href) === false ) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
cosmeticFiltering.onDOMContentLoaded();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Observe changes in the DOM
|
// 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/
|
// This fixes http://acid3.acidtests.org/
|
||||||
if ( document.body ) {
|
if ( document.body ) {
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/176
|
// https://github.com/gorhill/httpswitchboard/issues/176
|
||||||
|
|
|
@ -21,20 +21,14 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
uDom.onLoad(function() {
|
||||||
|
// Open links in the proper window
|
||||||
/******************************************************************************/
|
uDom('a').attr('target', '_blank');
|
||||||
|
uDom('a[href*="dashboard.html"]').attr('target', '_parent');
|
||||||
// Open links in the proper window
|
uDom('.whatisthis').on('click', function() {
|
||||||
$('a').attr('target', '_blank');
|
uDom(this)
|
||||||
$('a[href*="dashboard.html"]').attr('target', '_parent');
|
.parent()
|
||||||
|
.find('.whatisthis-expandable')
|
||||||
$('.whatisthis').on('click', function() {
|
.toggleClass('whatisthis-expanded');
|
||||||
$(this).parent()
|
});
|
||||||
.find('.whatisthis-expandable')
|
|
||||||
.toggleClass('whatisthis-expanded');
|
|
||||||
});
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,31 +23,41 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var loadDashboardPanel = function(hash) {
|
/******************************************************************************/
|
||||||
var button = $(hash);
|
|
||||||
var url = button.data('dashboardPanelUrl');
|
var loadDashboardPanel = function(tab) {
|
||||||
$('iframe')[0].src = url;
|
var tabButton = uDom('[data-dashboard-panel-url="' + tab + '"]');
|
||||||
$('.tabButton').each(function(){
|
if ( !tabButton ) {
|
||||||
var button = $(this);
|
return;
|
||||||
button.toggleClass('selected', button.data('dashboardPanelUrl') === url);
|
}
|
||||||
});
|
uDom('iframe').attr('src', tab);
|
||||||
}
|
uDom('.tabButton').toggleClass('selected', false);
|
||||||
|
tabButton.toggleClass('selected', true);
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onTabClickHandler = function() {
|
var onTabClickHandler = function() {
|
||||||
loadDashboardPanel(window.location.hash);
|
loadDashboardPanel(uDom(this).attr('data-dashboard-panel-url'));
|
||||||
}
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
$(function() {
|
uDom.onLoad(function() {
|
||||||
$(window).on('hashchange', onTabClickHandler);
|
var matches = window.location.search.slice(1).match(/\??(tab=([^&]+))?(.*)$/);
|
||||||
var hash = window.location.hash;
|
var tab = '', q = '';
|
||||||
if ( hash.length < 2 ) {
|
if ( matches && matches.length === 4 ) {
|
||||||
hash = '#thirdparty-filters';
|
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);
|
||||||
});
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
17
js/i18n.js
17
js/i18n.js
|
@ -20,18 +20,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Helper to deal with the i18n'ing of HTML files.
|
// Helper to deal with the i18n'ing of HTML files.
|
||||||
// jQuery must be present at this point.
|
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
uDom.onLoad(function() {
|
||||||
var i;
|
var fillin = function() {
|
||||||
var fillin = function(elem) {
|
this.innerHTML = chrome.i18n.getMessage(this.getAttribute('data-i18n'));
|
||||||
var key = elem.getAttribute("data-i18n");
|
|
||||||
elem.innerHTML = chrome.i18n.getMessage(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 µb = µBlock;
|
||||||
var r = {
|
var r = {
|
||||||
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
||||||
|
@ -39,7 +39,8 @@ var getStats = function(request, callback) {
|
||||||
pageBlockedRequestCount: 0,
|
pageBlockedRequestCount: 0,
|
||||||
pageAllowedRequestCount: 0,
|
pageAllowedRequestCount: 0,
|
||||||
netFilteringSwitch: false,
|
netFilteringSwitch: false,
|
||||||
cosmeticFilteringSwitch: false
|
cosmeticFilteringSwitch: false,
|
||||||
|
logBlockedRequests: µb.userSettings.logBlockedRequests
|
||||||
};
|
};
|
||||||
var pageStore = µb.pageStoreFromTabId(request.tabId);
|
var pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||||
if ( pageStore ) {
|
if ( pageStore ) {
|
||||||
|
@ -157,7 +158,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
response = {
|
response = {
|
||||||
collapse: µBlock.userSettings.collapseBlocked,
|
collapse: µBlock.userSettings.collapseBlocked,
|
||||||
blockedRequests: pageStore ? pageStore.blockedRequests : {}
|
blockedRequests: pageStore ? pageStore.blockedRequests : {}
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check a single request
|
// Check a single request
|
||||||
|
@ -165,7 +166,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
response = {
|
response = {
|
||||||
collapse: µBlock.userSettings.collapseBlocked,
|
collapse: µBlock.userSettings.collapseBlocked,
|
||||||
blocked: pageStore && pageStore.blockedRequests[request.url]
|
blocked: pageStore && pageStore.blockedRequests[request.url]
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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
|
// about.js
|
||||||
|
|
||||||
(function() {
|
(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
|
// 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
|
// already logged, since the request stats are cached for a while after
|
||||||
// the page is no longer visible in a browser tab.
|
// the page is no longer visible in a browser tab.
|
||||||
µb.updateBadge(this.tabId);
|
µb.updateBadge(this.tabId);
|
||||||
|
|
||||||
if ( block === false ) {
|
if ( reason === false ) {
|
||||||
this.perLoadAllowedRequestCount++;
|
this.perLoadAllowedRequestCount++;
|
||||||
µb.localSettings.allowedRequestCount++;
|
µb.localSettings.allowedRequestCount++;
|
||||||
return;
|
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/7
|
||||||
// https://github.com/gorhill/uBlock/issues/12
|
// 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
|
// Update badge, incrementally
|
||||||
|
|
||||||
// rhill 2013-11-09: well this sucks, I can't update icon/badge
|
// 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.
|
// notifying me, and this causes internal cached state to be out of sync.
|
||||||
|
|
||||||
PageStore.prototype.updateBadge = function() {
|
PageStore.prototype.updateBadge = function() {
|
||||||
|
|
83
js/popup.js
83
js/popup.js
|
@ -24,12 +24,10 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var stats;
|
var stats;
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// https://github.com/gorhill/httpswitchboard/issues/345
|
// 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() {
|
var renderStats = function() {
|
||||||
if ( !stats || !document.getElementById('switch') ) {
|
if ( !stats ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uDom('#gotoLog').toggleClass('enabled', stats.logBlockedRequests);
|
||||||
|
|
||||||
var blocked = stats.pageBlockedRequestCount;
|
var blocked = stats.pageBlockedRequestCount;
|
||||||
var total = stats.pageAllowedRequestCount + blocked;
|
var total = stats.pageAllowedRequestCount + blocked;
|
||||||
var elem = document.getElementById('page-blocked');
|
var html = [];
|
||||||
if ( total === 0 ) {
|
if ( total === 0 ) {
|
||||||
elem.innerHTML = '0';
|
html.push('0');
|
||||||
} else {
|
} else {
|
||||||
elem.innerHTML = [
|
html.push(
|
||||||
formatNumber(blocked),
|
formatNumber(blocked),
|
||||||
'<span class="dim"> or ',
|
'<span class="dim"> or ',
|
||||||
(blocked * 100 / total).toFixed(0),
|
(blocked * 100 / total).toFixed(0),
|
||||||
'%</span>'
|
'%</span>'
|
||||||
].join('');
|
);
|
||||||
}
|
}
|
||||||
|
uDom('#page-blocked').html(html.join(''));
|
||||||
|
|
||||||
blocked = stats.globalBlockedRequestCount;
|
blocked = stats.globalBlockedRequestCount;
|
||||||
total = stats.globalAllowedRequestCount + blocked;
|
total = stats.globalAllowedRequestCount + blocked;
|
||||||
elem = document.getElementById('total-blocked');
|
html = [];
|
||||||
if ( total === 0 ) {
|
if ( total === 0 ) {
|
||||||
elem.innerHTML = '0';
|
html.push('0');
|
||||||
} else {
|
} else {
|
||||||
elem.innerHTML = [
|
html.push(
|
||||||
formatNumber(blocked),
|
formatNumber(blocked),
|
||||||
'<span class="dim"> or ',
|
'<span class="dim"> or ',
|
||||||
(blocked * 100 / total).toFixed(0),
|
(blocked * 100 / total).toFixed(0),
|
||||||
'%</span>'
|
'%</span>'
|
||||||
].join('');
|
);
|
||||||
}
|
}
|
||||||
|
uDom('#total-blocked').html(html.join(''));
|
||||||
|
|
||||||
toggleClassName(
|
uDom('#switch .fa').toggleClass(
|
||||||
document.querySelector('#switch .fa'),
|
|
||||||
'off',
|
'off',
|
||||||
stats.pageURL === '' || !stats.netFilteringSwitch
|
stats.pageURL === '' || !stats.netFilteringSwitch
|
||||||
);
|
);
|
||||||
|
@ -154,34 +134,53 @@ var handleNetFilteringSwitch = function() {
|
||||||
if ( !stats || !stats.pageURL ) {
|
if ( !stats || !stats.pageURL ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
toggleClassName(this, 'off');
|
var off = uDom(this).toggleClass('off').hasClassName('off');
|
||||||
messaging.tell({
|
messaging.tell({
|
||||||
what: 'toggleNetFiltering',
|
what: 'toggleNetFiltering',
|
||||||
hostname: stats.pageHostname,
|
hostname: stats.pageHostname,
|
||||||
state: !hasClassName(this, 'off'),
|
state: !off,
|
||||||
tabId: stats.tabId
|
tabId: stats.tabId
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var renderHeader = function() {
|
var gotoDashboard = function() {
|
||||||
var hdr = document.getElementById('version');
|
messaging.tell({
|
||||||
hdr.innerHTML = hdr.innerHTML + 'v' + chrome.runtime.getManifest().version;
|
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() {
|
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
|
// Make menu only when popup html is fully loaded
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
uDom.onLoad(function() {
|
||||||
renderHeader();
|
renderHeader();
|
||||||
renderStats();
|
renderStats();
|
||||||
installEventHandlers();
|
installEventHandlers();
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
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
|
// TODO: use data-* to declare simple settings
|
||||||
|
|
||||||
var onUserSettingsReceived = function(details) {
|
var onUserSettingsReceived = function(details) {
|
||||||
$('#collapse-blocked')
|
uDom('#collapse-blocked')
|
||||||
.attr('checked', details.collapseBlocked === true)
|
.attr('checked', details.collapseBlocked === true)
|
||||||
.on('change', function(){
|
.on('change', function(){
|
||||||
changeUserSettings('collapseBlocked', $(this).is(':checked'));
|
changeUserSettings('collapseBlocked', this.checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#icon-badge')
|
uDom('#icon-badge')
|
||||||
.attr('checked', details.showIconBadge === true)
|
.attr('checked', details.showIconBadge === true)
|
||||||
.on('change', function(){
|
.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;
|
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 requestHostname = µburi.hostname;
|
||||||
var requestPath = µburi.path;
|
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;
|
||||||
|
|
||||||
|
})();
|
23
js/utils.js
23
js/utils.js
|
@ -40,10 +40,18 @@ var gotoURL = function(details) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var gotoExtensionURL = function(url) {
|
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 removeFragment = function(url) {
|
||||||
var pos = url.indexOf('#');
|
var pos = url.indexOf('#');
|
||||||
if ( pos < 0 ) {
|
if ( pos < 0 ) {
|
||||||
|
@ -54,26 +62,19 @@ var gotoExtensionURL = function(url) {
|
||||||
|
|
||||||
var tabIndex = 9999;
|
var tabIndex = 9999;
|
||||||
var targetUrl = chrome.extension.getURL(url);
|
var targetUrl = chrome.extension.getURL(url);
|
||||||
var urlToFind = removeFragment(targetUrl);
|
|
||||||
|
|
||||||
var currentWindow = function(tabs) {
|
var currentWindow = function(tabs) {
|
||||||
var updateProperties = { active: true };
|
var updateProperties = { active: true };
|
||||||
var i = tabs.length;
|
var i = tabs.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
if ( removeFragment(tabs[i].url) !== urlToFind ) {
|
if ( removeQuery(tabs[i].url) !== removeQuery(targetUrl) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If current tab in dashboard is different, force the new one, if
|
// If current tab in dashboard is different, force the new one, if
|
||||||
// there is one, to be activated.
|
// there is one, to be activated.
|
||||||
if ( tabs[i].url !== targetUrl ) {
|
if ( tabs[i].url !== targetUrl ) {
|
||||||
if ( hasFragment(targetUrl) ) {
|
updateProperties.url = 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);
|
chrome.tabs.update(tabs[i].id, updateProperties);
|
||||||
return;
|
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;
|
color: white;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -40,6 +41,17 @@ p {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: center;
|
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 {
|
#switch-hint {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #888;
|
color: #888;
|
||||||
|
@ -56,16 +68,17 @@ p {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#switch .fa {
|
#gotoLog {
|
||||||
font-size: 64px;
|
display: none;
|
||||||
color: green;
|
font-size: 14px;
|
||||||
|
color: gray;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
#switch .fa:hover {
|
#gotoLog.hover {
|
||||||
opacity: 0.9;
|
color: #444;
|
||||||
}
|
}
|
||||||
#switch .fa.off {
|
#gotoLog.enabled {
|
||||||
color: #ccc;
|
display: inline;
|
||||||
}
|
}
|
||||||
#options {
|
#options {
|
||||||
margin: 16px 0 0 0;
|
margin: 16px 0 0 0;
|
||||||
|
@ -80,17 +93,18 @@ p {
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<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>
|
<div>
|
||||||
<p id="switch"><span class="fa"></span></p>
|
<p id="switch"><span class="fa"></span></p>
|
||||||
<p id="switch-hint" data-i18n="popupPowerSwitchInfo"></p>
|
<p id="switch-hint" data-i18n="popupPowerSwitchInfo"></p>
|
||||||
<p style="font-size: 16px;" data-i18n="popupBlockedRequestPrompt"></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="page-blocked">?</p>
|
||||||
<p id="stats" data-i18n="popupBlockedSinceInstallPrompt"></p>
|
<p id="stats" data-i18n="popupBlockedSinceInstallPrompt"></p>
|
||||||
<p id="total-blocked">?</p>
|
<p id="total-blocked">?</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="js/udom.js"></script>
|
||||||
<script src="js/i18n.js"></script>
|
<script src="js/i18n.js"></script>
|
||||||
<script src="js/messaging-client.js"></script>
|
<script src="js/messaging-client.js"></script>
|
||||||
<script src="js/popup.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>
|
<li><input id="icon-badge" type="checkbox"> <span data-i18n="settingsIconBadgePrompt"></span>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script src="lib/jquery-2.min.js"></script>
|
<script src="js/udom.js"></script>
|
||||||
<script src="js/i18n.js"></script>
|
<script src="js/i18n.js"></script>
|
||||||
<script src="js/dashboard-common.js"></script>
|
<script src="js/dashboard-common.js"></script>
|
||||||
<script src="js/messaging-client.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