mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
this addresses half of #58: find list(s) from which a static network filter originates
This commit is contained in:
parent
74ad47bc71
commit
060a43fe81
11 changed files with 505 additions and 110 deletions
|
@ -459,6 +459,10 @@
|
|||
"message":"even if",
|
||||
"description":"Used in the static filtering wizard"
|
||||
},
|
||||
"loggerStaticFilteringFinderSentence1":{
|
||||
"message":"Static filter {{filter}} found in:",
|
||||
"description":"Below this sentence, the filter lists in which the filter was found"
|
||||
},
|
||||
"aboutChangelog":{
|
||||
"message":"Change log",
|
||||
"description":"English: Change log"
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<script src="js/tab.js"></script>
|
||||
<script src="js/traffic.js"></script>
|
||||
<script src="js/contextmenu.js"></script>
|
||||
<script src="js/reverselookup.js"></script>
|
||||
<script src="js/start.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -189,6 +189,9 @@ body:not(.popupOn) #content tr.canMtx td:nth-of-type(2) {
|
|||
body:not(.popupOn) #content tr.canMtx td:nth-of-type(2):hover {
|
||||
background: #ccc;
|
||||
}
|
||||
#content tr.cat_net[data-filter] td:nth-of-type(3) {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
#content tr.cat_net td:nth-of-type(4),
|
||||
#content tr.cat_cosmetic td:nth-of-type(4) {
|
||||
font: 12px monospace;
|
||||
|
@ -275,7 +278,7 @@ body[dir="rtl"] #popupContainer > div {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#urlFilteringMenu {
|
||||
.modalDialog {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border: 0;
|
||||
bottom: 0;
|
||||
|
@ -287,9 +290,10 @@ body[dir="rtl"] #popupContainer > div {
|
|||
z-index: 400;
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog {
|
||||
.modalDialog .dialog {
|
||||
background-color: white;
|
||||
border: 2px solid white;
|
||||
box-sizing: border-box;
|
||||
left: 10%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
@ -298,11 +302,11 @@ body[dir="rtl"] #popupContainer > div {
|
|||
width: 80%;
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog p {
|
||||
#netFilteringDialog .dialog p {
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog select {
|
||||
#netFilteringDialog .dialog select {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
|
@ -313,7 +317,7 @@ body[dir="rtl"] #popupContainer > div {
|
|||
padding: 0.2em;
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog > div.preview {
|
||||
#netFilteringDialog .dialog > div.preview {
|
||||
/* http://lea.verou.me/css3patterns/ */
|
||||
background-color: #aaa;
|
||||
background-image:
|
||||
|
@ -337,33 +341,33 @@ body[dir="rtl"] #popupContainer > div {
|
|||
background-size: 18px 18px;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.preview > * {
|
||||
#netFilteringDialog .dialog > div.preview > * {
|
||||
max-width: 100%;
|
||||
max-height: 40vh;
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog table {
|
||||
#netFilteringDialog .dialog table {
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
#urlFilteringMenu .dialog table > colgroup > col:nth-of-type(1) {
|
||||
#netFilteringDialog .dialog table > colgroup > col:nth-of-type(1) {
|
||||
width: 3.8em;
|
||||
}
|
||||
#urlFilteringMenu .dialog table > colgroup > col:nth-of-type(2) {
|
||||
#netFilteringDialog .dialog table > colgroup > col:nth-of-type(2) {
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog td {
|
||||
#netFilteringDialog .dialog td {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.headers {
|
||||
#netFilteringDialog .dialog > div.headers {
|
||||
border-bottom: 1px solid #888;
|
||||
position: relative;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.headers > span.header {
|
||||
#netFilteringDialog .dialog > div.headers > span.header {
|
||||
background-color: #eee;
|
||||
border: 1px solid #aaa;
|
||||
border-bottom: 1px solid #888;
|
||||
|
@ -380,45 +384,45 @@ body[dir="rtl"] #popupContainer > div {
|
|||
text-align: center;
|
||||
top: 1px;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.headers > span.header.selected {
|
||||
#netFilteringDialog .dialog > div.headers > span.header.selected {
|
||||
background-color: white;
|
||||
border-color: #888;
|
||||
border-bottom: 1px solid white;
|
||||
color: black;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.headers > span.tools {
|
||||
#netFilteringDialog .dialog > div.headers > span.tools {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
body[dir="ltr"] #urlFilteringMenu .dialog > div.headers > span.tools {
|
||||
body[dir="ltr"] #netFilteringDialog .dialog > div.headers > span.tools {
|
||||
right: 0.1em;
|
||||
}
|
||||
body[dir="rtl"] #urlFilteringMenu .dialog > div.headers > span.tools {
|
||||
body[dir="rtl"] #netFilteringDialog .dialog > div.headers > span.tools {
|
||||
left: 0.1em;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.headers > span.tools > span {
|
||||
#netFilteringDialog .dialog > div.headers > span.tools > span {
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers {
|
||||
#netFilteringDialog .dialog > div.containers {
|
||||
height: 40vh;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div {
|
||||
#netFilteringDialog .dialog > div.containers > div {
|
||||
display: none;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.selected {
|
||||
#netFilteringDialog .dialog > div.containers > div.selected {
|
||||
display: block;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic > table.toolbar select {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic > table.toolbar select {
|
||||
font: 14px;
|
||||
height: 2em;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic > table.toolbar #saveRules {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic > table.toolbar #saveRules {
|
||||
background-color: #ffe;
|
||||
border: 1px solid #ddc;
|
||||
border-radius: 4px;
|
||||
|
@ -428,37 +432,37 @@ body[dir="rtl"] #urlFilteringMenu .dialog > div.headers > span.tools {
|
|||
padding: 0.25em 0.5em;
|
||||
visibility: hidden;
|
||||
}
|
||||
body.dirty #urlFilteringMenu .dialog > div.containers > div.dynamic > table.toolbar #saveRules {
|
||||
body.dirty #netFilteringDialog .dialog > div.containers > div.dynamic > table.toolbar #saveRules {
|
||||
visibility: visible;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic > table.toolbar #saveRules:hover {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic > table.toolbar #saveRules:hover {
|
||||
color: black;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic > table.toolbar tr.entry {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic > table.toolbar tr.entry {
|
||||
display: none;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry {
|
||||
background-color: #e6e6e6;
|
||||
border: 0;
|
||||
border-bottom: 1px solid white;
|
||||
font-size: 13px;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry:hover {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td:first-of-type {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td:first-of-type {
|
||||
border: 0;
|
||||
border-right: 1px solid white;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
height: 2em;
|
||||
width: 100%;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
display: inline-block;
|
||||
|
@ -467,80 +471,98 @@ body.dirty #urlFilteringMenu .dialog > div.containers > div.dynamic > table.tool
|
|||
visibility: hidden;
|
||||
width: 33.33%;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.allow {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.allow {
|
||||
background-color: rgba(0, 160, 0, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.allow {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.allow {
|
||||
background-color: rgba(255, 194, 57, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.noop {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.noop {
|
||||
background-color: rgba(108, 108, 108, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.noop {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.noop {
|
||||
background-color: rgba(96, 96, 96, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.block {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.block {
|
||||
background-color: rgba(192, 0, 0, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.block {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.block {
|
||||
background-color: rgba(0, 19, 110, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.allow {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.allow {
|
||||
background-color: rgba(0, 160, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.allow {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.allow {
|
||||
background-color: rgba(255, 194, 57, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.noop {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.noop {
|
||||
background-color: rgba(108, 108, 108, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.block {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.block {
|
||||
background-color: rgba(192, 0, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.block {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action.own.block {
|
||||
background-color: rgba(0, 19, 110, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action:not(.own):hover > span {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action:not(.own):hover > span {
|
||||
opacity: 0.2;
|
||||
visibility: visible;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action:not(.own):hover > span:hover {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action:not(.own):hover > span:hover {
|
||||
opacity: 0.75;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.allow {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.allow {
|
||||
background-color: rgb(0, 160, 0);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.allow {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.allow {
|
||||
background-color: rgb(255, 194, 57);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.noop {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.noop {
|
||||
background-color: rgb(108, 108, 108);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.block {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.block {
|
||||
background-color: rgb(192, 0, 0);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.block {
|
||||
body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td > div.action > span.block {
|
||||
background-color: rgb(0, 19, 110);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.dynamic tr.entry > td.url {
|
||||
#netFilteringDialog .dialog > div.containers > div.dynamic tr.entry > td.url {
|
||||
overflow: hidden;
|
||||
padding-left: 4px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.static > p {
|
||||
#netFilteringDialog .dialog > div.containers > div.static > p {
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.static textarea {
|
||||
#netFilteringDialog .dialog > div.containers > div.static textarea {
|
||||
box-sizing: border-box;
|
||||
direction: ltr;
|
||||
height: 6em;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.containers > div.static > p:nth-of-type(2) {
|
||||
#netFilteringDialog .dialog > div.containers > div.static > p:nth-of-type(2) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#filterFinderDialog .dialog {
|
||||
padding: 1em;
|
||||
}
|
||||
#filterFinderDialog .dialog code {
|
||||
background: #eee;
|
||||
padding: 3px;
|
||||
}
|
||||
#filterFinderDialog .dialog ul {
|
||||
font-size: larger;
|
||||
}
|
||||
#filterFinderDialog .dialog > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
#filterFinderDialog .dialog > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uMatrix - a browser extension to benchmark browser session.
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2015 Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -16,7 +16,7 @@
|
|||
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/sessbench
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* jshint boss: true */
|
||||
|
@ -32,9 +32,9 @@
|
|||
|
||||
// Adjust top padding of content table, to match that of toolbar height.
|
||||
|
||||
document.getElementById('content').style.setProperty(
|
||||
uDom.nodeFromId('content').style.setProperty(
|
||||
'margin-top',
|
||||
document.getElementById('toolbar').offsetHeight + 'px'
|
||||
uDom.nodeFromId('toolbar').offsetHeight + 'px'
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -51,7 +51,8 @@ var allTabIds = {};
|
|||
var allTabIdsToken;
|
||||
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
||||
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
||||
var urlFilteringMenu = document.querySelector('#urlFilteringMenu');
|
||||
var netFilteringDialog = uDom.nodeFromId('netFilteringDialog');
|
||||
var filterFinderDialog = uDom.nodeFromId('filterFinderDialog');
|
||||
|
||||
var prettyRequestTypes = {
|
||||
'main_frame': 'doc',
|
||||
|
@ -159,19 +160,19 @@ var filterDecompiler = (function() {
|
|||
var opts = [];
|
||||
var vfields = compiled.split('\v');
|
||||
var filter = '';
|
||||
var bits = parseInt(vfields[1], 16) | 0;
|
||||
var bits = parseInt(vfields[0], 16) | 0;
|
||||
|
||||
if ( bits & 0x01 ) {
|
||||
filter += '@@';
|
||||
}
|
||||
|
||||
var fid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = fid !== '.' ? vfields[4].split('\t') : [];
|
||||
var fid = vfields[1] === '.' ? '.' : vfields[2];
|
||||
var tfields = fid !== '.' ? vfields[3].split('\t') : [];
|
||||
var tfield0 = tfields[0];
|
||||
|
||||
switch ( fid ) {
|
||||
case '.':
|
||||
filter += '||' + vfields[3] + '^';
|
||||
filter += '||' + vfields[2] + '^';
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
|
@ -258,14 +259,13 @@ var filterDecompiler = (function() {
|
|||
|
||||
var toRegex = function(compiled) {
|
||||
var vfields = compiled.split('\v');
|
||||
var fid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = fid !== '.' ? vfields[4].split('\t') : [];
|
||||
var fid = vfields[1] === '.' ? '.' : vfields[2];
|
||||
var tfields = fid !== '.' ? vfields[3].split('\t') : [];
|
||||
var reStr;
|
||||
|
||||
switch ( fid ) {
|
||||
case '.':
|
||||
reStr = vfields[3]
|
||||
.replace(reEscape, '\\$&');
|
||||
reStr = vfields[2].replace(reEscape, '\\$&');
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
|
@ -343,6 +343,7 @@ var createRow = function(layout) {
|
|||
tr.className = '';
|
||||
tr.removeAttribute('data-hn-page');
|
||||
tr.removeAttribute('data-hn-frame');
|
||||
tr.removeAttribute('data-filter');
|
||||
} else {
|
||||
tr = document.createElement('tr');
|
||||
}
|
||||
|
@ -431,6 +432,7 @@ var renderNetLogEntry = function(tr, entry) {
|
|||
filter = filter.slice(3);
|
||||
if ( filteringType === 's' ) {
|
||||
td.textContent = filterDecompiler.toString(filter);
|
||||
tr.setAttribute('data-filter', filter);
|
||||
} else {
|
||||
td.textContent = filter;
|
||||
}
|
||||
|
@ -587,7 +589,7 @@ var synchronizeTabIds = function(newTabIds) {
|
|||
}
|
||||
}
|
||||
|
||||
var select = document.getElementById('pageSelector');
|
||||
var select = uDom.nodeFromId('pageSelector');
|
||||
var selectValue = select.value;
|
||||
var tabIds = Object.keys(newTabIds).sort(function(a, b) {
|
||||
return newTabIds[a].localeCompare(newTabIds[b]);
|
||||
|
@ -692,8 +694,8 @@ var readLogBuffer = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var pageSelectorChanged = function() {
|
||||
var style = document.getElementById('tabFilterer');
|
||||
var tabClass = document.getElementById('pageSelector').value;
|
||||
var style = uDom.nodeFromId('tabFilterer');
|
||||
var tabClass = uDom.nodeFromId('pageSelector').value;
|
||||
var sheet = style.sheet;
|
||||
while ( sheet.cssRules.length !== 0 ) {
|
||||
sheet.deleteRule(0);
|
||||
|
@ -713,7 +715,7 @@ var pageSelectorChanged = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var reloadTab = function() {
|
||||
var tabClass = document.getElementById('pageSelector').value;
|
||||
var tabClass = uDom.nodeFromId('pageSelector').value;
|
||||
var tabId = tabIdFromClassName(tabClass);
|
||||
if ( tabId === 'bts' || tabId === '' ) {
|
||||
return;
|
||||
|
@ -746,7 +748,7 @@ var onMaxEntriesChanged = function() {
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var filteringDialog = (function() {
|
||||
var netFilteringManager = (function() {
|
||||
var targetRow = null;
|
||||
var dialog = null;
|
||||
var createdStaticFilters = {};
|
||||
|
@ -856,8 +858,8 @@ var filteringDialog = (function() {
|
|||
var onClick = function(ev) {
|
||||
var target = ev.target;
|
||||
|
||||
// click outside the url filtering menu
|
||||
if ( target.id === 'urlFilteringMenu' ) {
|
||||
// click outside the dialog proper
|
||||
if ( target.classList.contains('modalDialog') ) {
|
||||
toggleOff();
|
||||
return;
|
||||
}
|
||||
|
@ -1217,14 +1219,14 @@ var filteringDialog = (function() {
|
|||
createPreview(targetType, targetURLs[0]);
|
||||
fillDynamicPane();
|
||||
fillStaticPane();
|
||||
document.body.appendChild(urlFilteringMenu);
|
||||
urlFilteringMenu.addEventListener('click', onClick, true);
|
||||
urlFilteringMenu.addEventListener('change', onSelectChange, true);
|
||||
urlFilteringMenu.addEventListener('input', onInputChange, true);
|
||||
document.body.appendChild(netFilteringDialog);
|
||||
netFilteringDialog.addEventListener('click', onClick, true);
|
||||
netFilteringDialog.addEventListener('change', onSelectChange, true);
|
||||
netFilteringDialog.addEventListener('input', onInputChange, true);
|
||||
};
|
||||
|
||||
var toggleOn = function(ev) {
|
||||
dialog = urlFilteringMenu.querySelector('.dialog');
|
||||
dialog = netFilteringDialog.querySelector('.dialog');
|
||||
targetRow = ev.target.parentElement;
|
||||
targetTabId = tabIdFromClassName(targetRow.className);
|
||||
targetType = targetRow.cells[4].textContent.trim() || '';
|
||||
|
@ -1245,10 +1247,104 @@ var filteringDialog = (function() {
|
|||
dialog = null;
|
||||
targetRow = null;
|
||||
targetURLs = [];
|
||||
urlFilteringMenu.removeEventListener('click', onClick, true);
|
||||
urlFilteringMenu.removeEventListener('change', onSelectChange, true);
|
||||
urlFilteringMenu.removeEventListener('input', onInputChange, true);
|
||||
document.body.removeChild(urlFilteringMenu);
|
||||
netFilteringDialog.removeEventListener('click', onClick, true);
|
||||
netFilteringDialog.removeEventListener('change', onSelectChange, true);
|
||||
netFilteringDialog.removeEventListener('input', onInputChange, true);
|
||||
document.body.removeChild(netFilteringDialog);
|
||||
};
|
||||
|
||||
return {
|
||||
toggleOn: toggleOn
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var reverseLookupManager = (function() {
|
||||
var rawFilter = '';
|
||||
var reSentence1 = /\{\{filter\}\}/g;
|
||||
var sentence1Template = vAPI.i18n('loggerStaticFilteringFinderSentence1');
|
||||
|
||||
var removeAllChildren = function(node) {
|
||||
while ( node.firstChild ) {
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
var onClick = function(ev) {
|
||||
var target = ev.target;
|
||||
|
||||
// click outside the dialog proper
|
||||
if ( target.classList.contains('modalDialog') ) {
|
||||
toggleOff();
|
||||
return;
|
||||
}
|
||||
|
||||
ev.stopPropagation();
|
||||
};
|
||||
|
||||
var reverseLookupDone = function(response) {
|
||||
var lists = response.matches;
|
||||
if ( Array.isArray(lists) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dialog = filterFinderDialog.querySelector('.dialog');
|
||||
var p = dialog.querySelector('p');
|
||||
removeAllChildren(p);
|
||||
var node;
|
||||
|
||||
reSentence1.lastIndex = 0;
|
||||
var matches = reSentence1.exec(sentence1Template);
|
||||
if ( matches === null ) {
|
||||
node = document.createTextNode(sentence1Template);
|
||||
} else {
|
||||
node = uDom.nodeFromSelector('#filterFinderDialogSentence1 > span').cloneNode(true);
|
||||
node.childNodes[0].textContent = sentence1Template.slice(0, matches.index);
|
||||
node.childNodes[1].textContent = rawFilter;
|
||||
node.childNodes[2].textContent = sentence1Template.slice(reSentence1.lastIndex);
|
||||
}
|
||||
p.appendChild(node);
|
||||
|
||||
var ul = dialog.querySelector('ul');
|
||||
removeAllChildren(ul);
|
||||
var list, li;
|
||||
for ( var i = 0; i < lists.length; i++ ) {
|
||||
list = lists[i];
|
||||
li = document.createElement('li');
|
||||
if ( list.supportURL ) {
|
||||
node = document.createElement('a');
|
||||
node.textContent = list.title;
|
||||
node.setAttribute('href', list.supportURL);
|
||||
node.setAttribute('target', '_blank');
|
||||
} else {
|
||||
node = document.createTextNode(list.title);
|
||||
}
|
||||
li.appendChild(node);
|
||||
ul.appendChild(li);
|
||||
}
|
||||
|
||||
document.body.appendChild(filterFinderDialog);
|
||||
filterFinderDialog.addEventListener('click', onClick, true);
|
||||
};
|
||||
|
||||
var toggleOn = function(ev) {
|
||||
var row = ev.target.parentElement;
|
||||
var filter = row.getAttribute('data-filter') || '';
|
||||
if ( filter === '' ) {
|
||||
return;
|
||||
}
|
||||
rawFilter = row.cells[2].textContent;
|
||||
messager.send({
|
||||
what: 'reverseLookupFilter',
|
||||
filter: filter
|
||||
}, reverseLookupDone);
|
||||
};
|
||||
|
||||
var toggleOff = function() {
|
||||
filterFinderDialog.removeEventListener('click', onClick, true);
|
||||
document.body.removeChild(filterFinderDialog);
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -1489,7 +1585,7 @@ var popupManager = (function() {
|
|||
realTabId = noTabId;
|
||||
}
|
||||
|
||||
container = document.getElementById('popupContainer');
|
||||
container = uDom.nodeFromId('popupContainer');
|
||||
|
||||
container.querySelector('div > span:nth-of-type(1)').addEventListener('click', toggleSize);
|
||||
container.querySelector('div > span:nth-of-type(2)').addEventListener('click', toggleOff);
|
||||
|
@ -1500,7 +1596,7 @@ var popupManager = (function() {
|
|||
popupObserver = new MutationObserver(resizePopup);
|
||||
container.appendChild(popup);
|
||||
|
||||
style = document.getElementById('popupFilterer');
|
||||
style = uDom.nodeFromId('popupFilterer');
|
||||
style.textContent = styleTemplate.replace('{{tabId}}', localTabId);
|
||||
|
||||
document.body.classList.add('popupOn');
|
||||
|
@ -1559,7 +1655,8 @@ uDom.onLoad(function() {
|
|||
uDom('#clear').on('click', clearBuffer);
|
||||
uDom('#maxEntries').on('change', onMaxEntriesChanged);
|
||||
uDom('#content table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn);
|
||||
uDom('#content').on('click', 'tr.cat_net > td:nth-of-type(4)', filteringDialog.toggleOn);
|
||||
uDom('#content').on('click', 'tr.cat_net > td:nth-of-type(4)', netFilteringManager.toggleOn);
|
||||
uDom('#content').on('click', 'tr[data-filter] > td:nth-of-type(3)', reverseLookupManager.toggleOn);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -66,6 +66,10 @@ var onMessage = function(request, sender, callback) {
|
|||
µb.reloadAllFilters(callback);
|
||||
return;
|
||||
|
||||
case 'reverseLookupFilter':
|
||||
µb.staticFilteringReverseLookup.lookup(request.filter, callback);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
79
src/js/reverselookup-worker.js
Normal file
79
src/js/reverselookup-worker.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2015 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 onmessage, postMessage */
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var listEntries = Object.create(null);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var lookup = function(details) {
|
||||
var matches = [];
|
||||
var entry, pos;
|
||||
for ( var path in listEntries ) {
|
||||
entry = listEntries[path];
|
||||
if ( entry === undefined ) {
|
||||
continue;
|
||||
}
|
||||
pos = entry.content.indexOf(details.filter);
|
||||
if ( pos === -1 ) {
|
||||
continue;
|
||||
}
|
||||
matches.push({
|
||||
title: entry.title,
|
||||
supportURL: entry.supportURL
|
||||
});
|
||||
}
|
||||
|
||||
postMessage({
|
||||
id: details.id,
|
||||
response: {
|
||||
filter: details.filter,
|
||||
matches: matches
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
onmessage = function(e) {
|
||||
var msg = e.data;
|
||||
|
||||
switch ( msg.what ) {
|
||||
case 'resetLists':
|
||||
listEntries = Object.create(null);
|
||||
break;
|
||||
|
||||
case 'setList':
|
||||
listEntries[msg.details.path] = msg.details;
|
||||
break;
|
||||
|
||||
case 'reverseLookup':
|
||||
lookup(msg);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
177
src/js/reverselookup.js
Normal file
177
src/js/reverselookup.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2015 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 µBlock */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.staticFilteringReverseLookup = (function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var worker = null;
|
||||
var workerTTL = 11 * 60 * 1000;
|
||||
var workerTTLTimer = null;
|
||||
var needLists = true;
|
||||
var messageId = 1;
|
||||
var pendingResponses = Object.create(null);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onWorkerMessage = function(e) {
|
||||
var msg = e.data;
|
||||
var callback = pendingResponses[msg.id];
|
||||
delete pendingResponses[msg.id];
|
||||
callback(msg.response);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var stopWorker = function() {
|
||||
workerTTLTimer = null;
|
||||
if ( worker === null ) {
|
||||
return;
|
||||
}
|
||||
worker.terminate();
|
||||
worker = null;
|
||||
needLists = true;
|
||||
pendingResponses = Object.create(null);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var initWorker = function(callback) {
|
||||
if ( worker === null ) {
|
||||
worker = new Worker('js/reverselookup-worker.js');
|
||||
worker.onmessage = onWorkerMessage;
|
||||
}
|
||||
|
||||
if ( needLists === false ) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
needLists = false;
|
||||
|
||||
var entries = Object.create(null);
|
||||
var countdown = 0;
|
||||
var path, entry;
|
||||
|
||||
var onListLoaded = function(details) {
|
||||
var entry = entries[details.path];
|
||||
worker.postMessage({
|
||||
what: 'setList',
|
||||
details: {
|
||||
path: details.path,
|
||||
title: entry.title || '',
|
||||
supportURL: entry.supportURL,
|
||||
content: details.content
|
||||
}
|
||||
});
|
||||
countdown -= 1;
|
||||
if ( countdown === 0 ) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
var µb = µBlock;
|
||||
|
||||
for ( path in µb.remoteBlacklists ) {
|
||||
if ( µb.remoteBlacklists.hasOwnProperty(path) === false ) {
|
||||
continue;
|
||||
}
|
||||
entry = µb.remoteBlacklists[path];
|
||||
if ( entry.off === true ) {
|
||||
continue;
|
||||
}
|
||||
entries[path] = {
|
||||
title: entry.title,
|
||||
supportURL: entry.supportURL || ''
|
||||
};
|
||||
countdown += 1;
|
||||
}
|
||||
|
||||
if ( countdown === 0 ) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
for ( path in entries ) {
|
||||
µb.getCompiledFilterList(path, onListLoaded);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var lookup = function(compiledFilter, callback) {
|
||||
if ( typeof callback !== 'function' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( workerTTLTimer !== null ) {
|
||||
clearTimeout(workerTTLTimer);
|
||||
workerTTLTimer = null;
|
||||
}
|
||||
|
||||
var onWorkerReady = function() {
|
||||
var id = messageId++;
|
||||
var message = {
|
||||
what: 'reverseLookup',
|
||||
id: id,
|
||||
filter: compiledFilter
|
||||
};
|
||||
pendingResponses[id] = callback;
|
||||
worker.postMessage(message);
|
||||
|
||||
// The worker will be shutdown after n minutes without being used.
|
||||
workerTTLTimer = vAPI.setTimeout(stopWorker, workerTTL);
|
||||
};
|
||||
|
||||
initWorker(onWorkerReady);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// This tells the worker that filter lists may have changed.
|
||||
|
||||
var resetLists = function() {
|
||||
needLists = true;
|
||||
if ( worker === null ) {
|
||||
return;
|
||||
}
|
||||
worker.postMessage({ what: 'resetLists' });
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
return {
|
||||
lookup: lookup,
|
||||
resetLists: resetLists,
|
||||
shutdown: stopWorker
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
|
@ -37,6 +37,18 @@ var µb = µBlock;
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.app.onShutdown = function() {
|
||||
µb.staticFilteringReverseLookup.shutdown();
|
||||
µb.staticNetFilteringEngine.reset();
|
||||
µb.sessionFirewall.reset();
|
||||
µb.permanentFirewall.reset();
|
||||
µb.permanentFirewall.reset();
|
||||
µb.sessionURLFiltering.reset();
|
||||
µb.permanentURLFiltering.reset();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Final initialization steps after all needed assets are in memory.
|
||||
// - Initialize internal state with maybe already existing tabs.
|
||||
// - Schedule next update operation.
|
||||
|
|
|
@ -160,11 +160,6 @@ histogram = function(label, categories) {
|
|||
|
||||
// Local helpers
|
||||
|
||||
// Could be replaced with encodeURIComponent/decodeURIComponent,
|
||||
// which seems faster on Firefox.
|
||||
var encode = JSON.stringify;
|
||||
var decode = JSON.parse;
|
||||
|
||||
var cachedParseInt = parseInt;
|
||||
|
||||
var atoi = function(s) {
|
||||
|
@ -1651,12 +1646,10 @@ FilterContainer.prototype.toSelfie = function() {
|
|||
var categoryToSelfie = function(dict) {
|
||||
var selfie = [];
|
||||
var bucket, ff, n, i, f;
|
||||
for ( var k in dict ) {
|
||||
for ( var token in dict ) {
|
||||
// No need for hasOwnProperty() here: there is no prototype chain.
|
||||
// We need to encode the key because there could be a `\n` or '\t'
|
||||
// character in it, which would trip the code at parse time.
|
||||
selfie.push('k2\t' + encode(k));
|
||||
bucket = dict[k];
|
||||
selfie.push('k2\t' + token);
|
||||
bucket = dict[token];
|
||||
selfie.push(bucket.fid + '\t' + bucket.toSelfie());
|
||||
if ( bucket.fid !== '[]' ) {
|
||||
continue;
|
||||
|
@ -1673,12 +1666,10 @@ FilterContainer.prototype.toSelfie = function() {
|
|||
|
||||
var categoriesToSelfie = function(dict) {
|
||||
var selfie = [];
|
||||
for ( var k in dict ) {
|
||||
for ( var key in dict ) {
|
||||
// No need for hasOwnProperty() here: there is no prototype chain.
|
||||
// We need to encode the key because there could be a `\n` or '\t'
|
||||
// character in it, which would trip the code at parse time.
|
||||
selfie.push('k1\t' + encode(k));
|
||||
selfie.push(categoryToSelfie(dict[k]));
|
||||
selfie.push('k1\t' + key);
|
||||
selfie.push(categoryToSelfie(dict[key]));
|
||||
}
|
||||
return selfie.join('\n');
|
||||
};
|
||||
|
@ -1722,13 +1713,13 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
|
|||
pos = line.indexOf('\t');
|
||||
what = line.slice(0, pos);
|
||||
if ( what === 'k1' ) {
|
||||
catKey = decode(line.slice(pos + 1));
|
||||
catKey = line.slice(pos + 1);
|
||||
subdict = dict[catKey] = Object.create(null);
|
||||
bucket = null;
|
||||
continue;
|
||||
}
|
||||
if ( what === 'k2' ) {
|
||||
tokenKey = decode(line.slice(pos + 1));
|
||||
tokenKey = line.slice(pos + 1);
|
||||
bucket = null;
|
||||
continue;
|
||||
}
|
||||
|
@ -2015,18 +2006,18 @@ FilterContainer.prototype.filterStringFromCompiled = function(compiled) {
|
|||
var opts = [];
|
||||
var vfields = compiled.split('\v');
|
||||
var filter = '';
|
||||
var bits = parseInt(vfields[1], 16) | 0;
|
||||
var bits = parseInt(vfields[0], 16) | 0;
|
||||
|
||||
if ( bits & 0x01 ) {
|
||||
filter += '@@';
|
||||
}
|
||||
|
||||
var rfid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = rfid !== '.' ? vfields[4].split('\t') : [];
|
||||
var rfid = vfields[1] === '.' ? '.' : vfields[2];
|
||||
var tfields = rfid !== '.' ? vfields[3].split('\t') : [];
|
||||
|
||||
switch ( rfid ) {
|
||||
case '.':
|
||||
filter += '||' + vfields[3] + '^';
|
||||
filter += '||' + vfields[2] + '^';
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
|
@ -2102,13 +2093,13 @@ FilterContainer.prototype.filterStringFromCompiled = function(compiled) {
|
|||
|
||||
FilterContainer.prototype.filterRegexFromCompiled = function(compiled, flags) {
|
||||
var vfields = compiled.split('\v');
|
||||
var rfid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = rfid !== '.' ? vfields[4].split('\t') : [];
|
||||
var rfid = vfields[1] === '.' ? '.' : vfields[2];
|
||||
var tfields = rfid !== '.' ? vfields[3].split('\t') : [];
|
||||
var re = null;
|
||||
|
||||
switch ( rfid ) {
|
||||
case '.':
|
||||
re = strToRegex(vfields[3], 0, flags);
|
||||
re = strToRegex(vfields[2], 0, flags);
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
|
@ -2476,7 +2467,7 @@ FilterContainer.prototype.toResultString = function(verbose) {
|
|||
if ( !verbose ) {
|
||||
return s;
|
||||
}
|
||||
s += 'n\v' + this.keyRegister + '\v' + this.tokenRegister + '\v';
|
||||
s += this.keyRegister + '\v' + this.tokenRegister + '\v';
|
||||
if ( this.tokenRegister === '.' ) {
|
||||
s += this.fRegister.rtCompile();
|
||||
} else {
|
||||
|
|
|
@ -400,6 +400,7 @@
|
|||
µb.cosmeticFilteringEngine.reset();
|
||||
µb.staticNetFilteringEngine.reset();
|
||||
µb.destroySelfie();
|
||||
µb.staticFilteringReverseLookup.resetLists();
|
||||
|
||||
// We need to build a complete list of assets to pull first: this is
|
||||
// because it *may* happens that some load operations are synchronous:
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<div id="templates" style="display: none;">
|
||||
<div id="renderedURLTemplate"><span><span></span><b></b><span></span></span></div>
|
||||
<div id="hiddenTemplate"><span style="display:none;"></span></div>
|
||||
<div id="urlFilteringMenu">
|
||||
<div id="netFilteringDialog" class="modalDialog">
|
||||
<div class="dialog">
|
||||
<div class="hide preview"></div>
|
||||
<div class="headers">
|
||||
|
@ -79,6 +79,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filterFinderDialog" class="modalDialog">
|
||||
<div class="dialog">
|
||||
<p></p>
|
||||
<ul></ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filterFinderDialogSentence1"><span><span></span><code></code><span></span></span></div>
|
||||
</div>
|
||||
|
||||
<script src="js/vapi-common.js"></script>
|
||||
|
|
Loading…
Reference in a new issue