filtering in logger + various small fixes

pull/2/head
gorhill 10 years ago
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">&#xf00d;</span>
<span id="clear" class="button fa disabled">&#xf12d;</span>
<span id="filterButton" class="button fa">&#xf0b0;</span><input id="filterExpression" type="text" placeholder="logFilterPrompt">
<span id="filterButton" class="button fa">&#xf0b0;</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">&#xf022;</button>
<button type="button" class="dropdown-menu-button fa tip-anchor-right">&#xf067;</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…
Cancel
Save