mirror of
https://github.com/gorhill/uMatrix.git
synced 2024-06-02 02:14:52 +12:00
filtering in logger + various small fixes
This commit is contained in:
parent
4142551c13
commit
8f2b473928
|
@ -583,6 +583,11 @@
|
|||
"description": "Message asking user to confirm reset"
|
||||
},
|
||||
|
||||
"loggerFilterInputPlaceholder" : {
|
||||
"message": "filter expression(s)",
|
||||
"description": "Appears in the input filed where filter expressions are entered"
|
||||
},
|
||||
|
||||
"mainBlockedPrompt1": {
|
||||
"message": "uMatrix has prevented the following page from loading:",
|
||||
"description": "English: uMatrix has prevented the following page from loading:"
|
||||
|
|
|
@ -43,19 +43,19 @@
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
html {
|
||||
body[dir="ltr"] {
|
||||
direction: ltr;
|
||||
}
|
||||
html.rtl {
|
||||
body[dir="rtl"] {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* http://stackoverflow.com/questions/2011142/how-to-change-the-style-of-title-attribute-inside-the-anchor-tag?answertab=votes */
|
||||
*[data-tip] {
|
||||
*[data-i18n-tip] {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
*[data-tip]:hover:after {
|
||||
*[data-i18n-tip]:hover:after {
|
||||
background-color: #fffffa;
|
||||
border: 1px solid gray;
|
||||
border-radius: 3px;
|
||||
|
@ -63,7 +63,6 @@ html.rtl {
|
|||
color: black;
|
||||
content: attr(data-tip);
|
||||
font: 12px sans-serif;
|
||||
left: -100%;
|
||||
line-height: 140%;
|
||||
min-width: 25vw;
|
||||
padding: 4px 6px;
|
||||
|
@ -73,11 +72,11 @@ html.rtl {
|
|||
white-space: pre-line;
|
||||
z-index: 20;
|
||||
}
|
||||
html.ltr .tip-anchor-left[data-tip]:hover:after,
|
||||
html.rtl .tip-anchor-right[data-tip]:hover:after {
|
||||
left: -5vw;
|
||||
body[dir="ltr"] .tip-anchor-left[data-i18n-tip]:hover:after,
|
||||
body[dir="rtl"] .tip-anchor-right[data-i18n-tip]:hover:after {
|
||||
left: -3vw;
|
||||
}
|
||||
html.ltr .tip-anchor-right[data-tip]:hover:after,
|
||||
html.rtl .tip-anchor-left[data-tip]:hover:after {
|
||||
right: -5vw;
|
||||
body[dir="ltr"] .tip-anchor-right[data-i18n-tip]:hover:after,
|
||||
body[dir="rtl"] .tip-anchor-left[data-i18n-tip]:hover:after {
|
||||
right: -3vw;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,13 @@ body #compactViewToggler.button:before {
|
|||
body.compactView #compactViewToggler.button:before {
|
||||
content: '\f103';
|
||||
}
|
||||
body.filterOff #toolbar #filterButton {
|
||||
#filterButton {
|
||||
opacity: 0.25;
|
||||
}
|
||||
#filterExpression.bad {
|
||||
body.f #filterButton {
|
||||
opacity: 1;
|
||||
}
|
||||
#filterInput.bad {
|
||||
background-color: #fee;
|
||||
}
|
||||
#maxEntries {
|
||||
|
@ -74,20 +77,23 @@ input:focus {
|
|||
width: 6em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(2) {
|
||||
width: 3em;
|
||||
width: 2.5em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(3) {
|
||||
width: 3em;
|
||||
width: 2.5em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(4) {
|
||||
width: 5em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(5) {
|
||||
width: calc(100% - 20em);
|
||||
width: calc(100% - 19em);
|
||||
}
|
||||
#content table tr {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
body.f table tr.f {
|
||||
display: none;
|
||||
}
|
||||
#content table tr:nth-of-type(2n+1) {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
@ -104,10 +110,6 @@ input:focus {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
body:not(.filterOff) #content table tr.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body #content td {
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
|
|
|
@ -118,11 +118,6 @@ body[dir="rtl"] #mtxSwitches > li:before {
|
|||
font: 110% FontAwesome;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
[data-i18n="matrixLoggerMenuEntry"]:before {
|
||||
content: '\f022';
|
||||
font: 110% FontAwesome;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
[data-i18n="matrixDashboardMenuEntry"]:before {
|
||||
content: '\f085';
|
||||
font: 110% FontAwesome;
|
||||
|
|
|
@ -52,6 +52,16 @@ while ( i-- ) {
|
|||
node.setAttribute('data-tip', vAPI.i18n(node.getAttribute('data-i18n-tip')));
|
||||
}
|
||||
|
||||
nodeList = document.querySelectorAll('input[placeholder]');
|
||||
i = nodeList.length;
|
||||
while ( i-- ) {
|
||||
node = nodeList[i];
|
||||
node.setAttribute(
|
||||
'placeholder',
|
||||
vAPI.i18n(node.getAttribute('placeholder')) || ''
|
||||
);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.i18n.renderElapsedTimeToString = function(tstamp) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/sessbench
|
||||
|
||||
TODO: cleanup/refactor
|
||||
*/
|
||||
|
||||
/* jshint boss: true */
|
||||
|
@ -33,10 +31,7 @@
|
|||
/******************************************************************************/
|
||||
|
||||
var messager = vAPI.messaging.channel('logger-ui.js');
|
||||
|
||||
var doc = document;
|
||||
var body = doc.body;
|
||||
var tbody = doc.querySelector('#content tbody');
|
||||
var tbody = document.querySelector('#content tbody');
|
||||
var trJunkyard = [];
|
||||
var tdJunkyard = [];
|
||||
var firstVarDataCol = 2; // currently, column 2 (0-based index)
|
||||
|
@ -116,7 +111,7 @@ var createCellAt = function(tr, index) {
|
|||
td.removeAttribute('colspan');
|
||||
td.textContent = '';
|
||||
} else {
|
||||
td = doc.createElement('td');
|
||||
td = document.createElement('td');
|
||||
}
|
||||
if ( mustAppend ) {
|
||||
tr.appendChild(td);
|
||||
|
@ -131,7 +126,7 @@ var createRow = function(layout) {
|
|||
if ( tr ) {
|
||||
tr.className = '';
|
||||
} else {
|
||||
tr = doc.createElement('tr');
|
||||
tr = document.createElement('tr');
|
||||
}
|
||||
for ( var index = 0; index < firstVarDataCol; index++ ) {
|
||||
createCellAt(tr, index);
|
||||
|
@ -198,7 +193,7 @@ var renderLogEntry = function(entry) {
|
|||
}
|
||||
if ( entry.d3 ) {
|
||||
tr.classList.add('blocked');
|
||||
tr.cells[fvdc].textContent = '---';
|
||||
tr.cells[fvdc].textContent = '--';
|
||||
} else {
|
||||
tr.cells[fvdc].textContent = '';
|
||||
}
|
||||
|
@ -229,6 +224,8 @@ var renderLogEntry = function(entry) {
|
|||
tr.classList.add('cat_' + entry.cat);
|
||||
}
|
||||
|
||||
rowFilterer.filterOne(tr);
|
||||
|
||||
tbody.insertBefore(tr, tbody.firstChild);
|
||||
};
|
||||
|
||||
|
@ -268,15 +265,15 @@ var renderLogEntries = function(response) {
|
|||
// Chromium:
|
||||
// body.scrollTop = good value
|
||||
// body.parentNode.scrollTop = 0
|
||||
if ( body.scrollTop !== 0 ) {
|
||||
body.scrollTop += yDelta;
|
||||
if ( document.body.scrollTop !== 0 ) {
|
||||
document.body.scrollTop += yDelta;
|
||||
return;
|
||||
}
|
||||
|
||||
// Firefox:
|
||||
// body.scrollTop = 0
|
||||
// body.parentNode.scrollTop = good value
|
||||
var parentNode = body.parentNode;
|
||||
var parentNode = document.body.parentNode;
|
||||
if ( parentNode && parentNode.scrollTop !== 0 ) {
|
||||
parentNode.scrollTop += yDelta;
|
||||
}
|
||||
|
@ -288,6 +285,7 @@ var truncateLog = function(size) {
|
|||
if ( size === 0 ) {
|
||||
size = 5000;
|
||||
}
|
||||
var tbody = document.querySelector('#content tbody');
|
||||
size = Math.min(size, 10000);
|
||||
var tr;
|
||||
while ( tbody.childElementCount > size ) {
|
||||
|
@ -356,7 +354,155 @@ var readLogBuffer = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMaxEntriesChanged = function() {
|
||||
var raw = uDom(this).val();
|
||||
try {
|
||||
maxEntries = parseInt(raw, 10);
|
||||
if ( isNaN(maxEntries) ) {
|
||||
maxEntries = 0;
|
||||
}
|
||||
} catch (e) {
|
||||
maxEntries = 0;
|
||||
}
|
||||
|
||||
messager.send({
|
||||
what: 'userSettings',
|
||||
name: 'maxLoggedRequests',
|
||||
value: maxEntries
|
||||
});
|
||||
|
||||
truncateLog(maxEntries);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var rowFilterer = (function() {
|
||||
var filters = [];
|
||||
|
||||
var parseInput = function() {
|
||||
filters = [];
|
||||
|
||||
var rawPart, not, hardBeg, hardEnd, reStr;
|
||||
var raw = uDom('#filterInput').val().trim();
|
||||
var rawParts = raw.split(/\s+/);
|
||||
var i = rawParts.length;
|
||||
while ( i-- ) {
|
||||
rawPart = rawParts[i];
|
||||
not = rawPart.charAt(0) === '!';
|
||||
if ( not ) {
|
||||
rawPart = rawPart.slice(1);
|
||||
}
|
||||
hardBeg = rawPart.charAt(0) === '[';
|
||||
if ( hardBeg ) {
|
||||
rawPart = rawPart.slice(1);
|
||||
}
|
||||
hardEnd = rawPart.slice(-1) === ']';
|
||||
if ( hardEnd ) {
|
||||
rawPart = rawPart.slice(0, -1);
|
||||
}
|
||||
if ( rawPart === '' ) {
|
||||
continue;
|
||||
}
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
||||
reStr = rawPart.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
||||
.replace(/\*/g, '.*');
|
||||
if ( hardBeg ) {
|
||||
reStr = '(?:^|\\s)' + reStr;
|
||||
}
|
||||
if ( hardEnd ) {
|
||||
reStr += '(?:\\s|$)';
|
||||
}
|
||||
filters.push({
|
||||
re: new RegExp(reStr, 'i'),
|
||||
r: !not
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var filterOne = function(tr) {
|
||||
var cl = tr.classList;
|
||||
// do not filter out doc boundaries, they help separate important
|
||||
// section of log.
|
||||
if ( cl.contains('doc') ) {
|
||||
return;
|
||||
}
|
||||
var ff = filters;
|
||||
var fcount = ff.length;
|
||||
if ( fcount === 0 ) {
|
||||
cl.remove('f');
|
||||
return;
|
||||
}
|
||||
var cc = tr.cells;
|
||||
var ccount = cc.length;
|
||||
var hit, j, f;
|
||||
// each filter expression must hit (implicit and-op)
|
||||
// if...
|
||||
// positive filter expression = there must one hit on any field
|
||||
// negative filter expression = there must be no hit on all fields
|
||||
for ( var i = 0; i < fcount; i++ ) {
|
||||
f = ff[i];
|
||||
hit = !f.r;
|
||||
for ( j = 0; j < ccount; j++ ) {
|
||||
if ( f.re.test(cc[j].innerText) ) {
|
||||
hit = f.r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !hit ) {
|
||||
cl.add('f');
|
||||
return;
|
||||
}
|
||||
}
|
||||
cl.remove('f');
|
||||
};
|
||||
|
||||
var filterAll = function() {
|
||||
// Special case: no filter
|
||||
if ( filters.length === 0 ) {
|
||||
uDom('#content tr').removeClass('f');
|
||||
return;
|
||||
}
|
||||
var tbody = document.querySelector('#content tbody');
|
||||
var rows = tbody.rows;
|
||||
var i = rows.length;
|
||||
while ( i-- ) {
|
||||
filterOne(rows[i]);
|
||||
}
|
||||
};
|
||||
|
||||
var onFilterChangedAsync = (function() {
|
||||
var timer = null;
|
||||
var commit = function() {
|
||||
timer = null;
|
||||
parseInput();
|
||||
filterAll();
|
||||
};
|
||||
return function() {
|
||||
if ( timer !== null ) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(commit, 750);
|
||||
};
|
||||
})();
|
||||
|
||||
var onFilterButton = function() {
|
||||
var cl = document.body.classList;
|
||||
cl.toggle('f', cl.contains('f') === false);
|
||||
};
|
||||
|
||||
uDom('#filterButton').on('click', onFilterButton);
|
||||
uDom('#filterInput').on('input', onFilterChangedAsync);
|
||||
|
||||
return {
|
||||
filterOne: filterOne,
|
||||
filterAll: filterAll
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var clearBuffer = function() {
|
||||
var tbody = document.querySelector('#content tbody');
|
||||
var tr;
|
||||
while ( tbody.firstChild !== null ) {
|
||||
tr = tbody.lastElementChild;
|
||||
|
@ -380,9 +526,9 @@ var cleanBuffer = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var toggleCompactView = function() {
|
||||
body.classList.toggle(
|
||||
document.body.classList.toggle(
|
||||
'compactView',
|
||||
body.classList.contains('compactView') === false
|
||||
document.body.classList.contains('compactView') === false
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -595,28 +741,6 @@ var popupManager = (function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMaxEntriesChanged = function() {
|
||||
var raw = uDom(this).val();
|
||||
try {
|
||||
maxEntries = parseInt(raw, 10);
|
||||
if ( isNaN(maxEntries) ) {
|
||||
maxEntries = 0;
|
||||
}
|
||||
} catch (e) {
|
||||
maxEntries = 0;
|
||||
}
|
||||
|
||||
messager.send({
|
||||
what: 'userSettings',
|
||||
name: 'maxLoggedRequests',
|
||||
value: maxEntries
|
||||
});
|
||||
|
||||
truncateLog(maxEntries);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uDom.onLoad(function() {
|
||||
readLogBuffer();
|
||||
|
||||
|
|
|
@ -1268,6 +1268,8 @@ var matrixSnapshotPoller = (function() {
|
|||
var matches = window.location.search.match(/(?:\?|&)tabId=([^&]+)/);
|
||||
if ( matches !== null ) {
|
||||
tabId = matches[1];
|
||||
// No need for logger button when embedded in logger
|
||||
uDom('[data-extension-url="logger-ui.html"]').remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ var selfieMagic = 'iscjsfsaolnm';
|
|||
// < this.cutoffLength = indexOf()
|
||||
// >= this.cutoffLength = binary search
|
||||
var cutoffLength = 256;
|
||||
var mustPunycode = /[^a-z0-9.-]/;
|
||||
var mustPunycode = /[^\w.*-]/;
|
||||
|
||||
var onChangedListeners = [];
|
||||
|
||||
|
@ -171,11 +171,6 @@ function parse(text, toAscii) {
|
|||
exceptions = {};
|
||||
rules = {};
|
||||
|
||||
// http://publicsuffix.org/list/:
|
||||
// "... all rules must be canonicalized in the normal way
|
||||
// for hostnames - lower-case, Punycode ..."
|
||||
text = text.toLowerCase();
|
||||
|
||||
var lineBeg = 0, lineEnd;
|
||||
var textEnd = text.length;
|
||||
var line, store, pos, tld;
|
||||
|
@ -207,10 +202,6 @@ function parse(text, toAscii) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( mustPunycode.test(line) ) {
|
||||
line = toAscii(line);
|
||||
}
|
||||
|
||||
// Is this an exception rule?
|
||||
if ( line.charAt(0) === '!' ) {
|
||||
store = exceptions;
|
||||
|
@ -219,6 +210,15 @@ function parse(text, toAscii) {
|
|||
store = rules;
|
||||
}
|
||||
|
||||
if ( mustPunycode.test(line) ) {
|
||||
line = toAscii(line);
|
||||
}
|
||||
|
||||
// http://publicsuffix.org/list/:
|
||||
// "... all rules must be canonicalized in the normal way
|
||||
// for hostnames - lower-case, Punycode ..."
|
||||
line = line.toLowerCase();
|
||||
|
||||
// Extract TLD
|
||||
pos = line.lastIndexOf('.');
|
||||
if ( pos < 0 ) {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<link rel="stylesheet" type="text/css" href="css/logger-ui.css">
|
||||
<title>uMatrix log</title>
|
||||
</head>
|
||||
<body class="compactView">
|
||||
<body class="compactView f">
|
||||
|
||||
<div id="toolbar">
|
||||
<span id="compactViewToggler" class="button fa"></span>
|
||||
<span id="clean" class="button fa disabled"></span>
|
||||
<span id="clear" class="button fa disabled"></span>
|
||||
<span id="filterButton" class="button fa"></span><input id="filterExpression" type="text" placeholder="logFilterPrompt">
|
||||
<span id="filterButton" class="button fa"></span><input id="filterInput" type="text" placeholder="loggerFilterInputPlaceholder">
|
||||
<input id="maxEntries" type="text" size="5" title="logMaxEntriesTip">
|
||||
</div>
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@
|
|||
|
||||
<!-- Yandex: float works correctly only if it is the first child -->
|
||||
<div class="toolbar alignRight">
|
||||
<button type="button" class="fa extensionURL tip-anchor-right" data-extension-url="logger-ui.html" data-i18n-tip="matrixLoggerMenuEntry"></button>
|
||||
<button type="button" class="dropdown-menu-button fa tip-anchor-right"></button>
|
||||
<div class="dropdown-menu">
|
||||
<ul>
|
||||
<li id="buttonRevertAll" class="dropdown-menu-entry" data-i18n="matrixRevertAllEntry">
|
||||
<li class="dropdown-menu-entry extensionURL" data-extension-url="logger-ui.html" data-i18n="matrixLoggerMenuEntry">
|
||||
<li class="dropdown-menu-entry extensionURL" data-extension-url="dashboard.html" data-i18n="matrixDashboardMenuEntry">
|
||||
</ul>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue