1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-18 17:02:27 +02:00

Add export-to-clipboard feature to logger

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/334

Additionally, a number of smallish issues following
refactoring of the logger code were addressed.
This commit is contained in:
Raymond Hill 2019-01-14 14:57:31 -05:00
parent 88a54d442d
commit 0edf53f508
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
8 changed files with 360 additions and 144 deletions

View File

@ -300,7 +300,7 @@
"description": "" "description": ""
}, },
"settingsNoLargeMediaPrompt":{ "settingsNoLargeMediaPrompt":{
"message":"Block media elements larger than {{input}} kB", "message":"Block media elements larger than {{input}} KB",
"description": "" "description": ""
}, },
"settingsNoRemoteFontsPrompt":{ "settingsNoRemoteFontsPrompt":{

View File

@ -51,6 +51,7 @@
.fa-icon > .fa-icon_exclamation-triangle { .fa-icon > .fa-icon_exclamation-triangle {
width: calc(1em * 1794 / 1792); width: calc(1em * 1794 / 1792);
} }
.fa-icon > .fa-icon_clipboard,
.fa-icon > .fa-icon_eye-dropper, .fa-icon > .fa-icon_eye-dropper,
.fa-icon > .fa-icon_eye-slash, .fa-icon > .fa-icon_eye-slash,
.fa-icon > .fa-icon_files-o, .fa-icon > .fa-icon_files-o,

View File

@ -23,8 +23,12 @@ textarea {
display: flex; display: flex;
flex-shrink: 0; flex-shrink: 0;
font-size: 120%; font-size: 120%;
justify-content: space-between;
margin: 0; margin: 0;
padding: 0.25em 0.5em; padding: 0.25em;
}
.permatoolbar > div {
display: flex;
} }
.permatoolbar .button { .permatoolbar .button {
cursor: pointer; cursor: pointer;
@ -59,24 +63,10 @@ body[dir="rtl"] #pageSelector {
} }
#info { #info {
fill: #ccc; fill: #ccc;
padding-left: 0.5em;
padding-right: 0.5em;
position: absolute;
} }
#info:hover { #info:hover {
fill: #000; fill: #000;
} }
body[dir="ltr"] #info {
right: 0;
}
body[dir="rtl"] #info {
left: 0;
}
@media (max-width: 540px) {
#info {
display: none;
}
}
/* /*
https://github.com/gorhill/uBlock/issues/3293 https://github.com/gorhill/uBlock/issues/3293
@ -204,17 +194,6 @@ body[dir="rtl"] #netInspector #filterExprPicker {
background-color: lightblue; background-color: lightblue;
border: 1px solid lightblue; border: 1px solid lightblue;
} }
#netInspector #settings {
padding-left: 0.5em;
padding-right: 0.5em;
position: absolute;
}
body[dir="ltr"] #netInspector #settings {
right: 0;
}
body[dir="rtl"] #netInspector #settings {
left: 0;
}
#netInspector .vscrollable { #netInspector .vscrollable {
overflow: hidden; overflow: hidden;
@ -278,6 +257,9 @@ body.colorBlind #vwRenderer .logEntry > div[data-status="2"],
body.colorBlind #netFilteringDialog > .panes > .details > div[data-status="2"] { body.colorBlind #netFilteringDialog > .panes > .details > div[data-status="2"] {
background-color: rgba(255, 194, 57, 0.1) background-color: rgba(255, 194, 57, 0.1)
} }
#vwRenderer .logEntry > div[data-tabid="-1"] {
text-shadow: 0 0 0.8em #444;
}
#vwRenderer .logEntry > div.cosmetic, #vwRenderer .logEntry > div.cosmetic,
#vwRenderer .logEntry > div.redirect { #vwRenderer .logEntry > div.redirect {
background-color: rgba(255, 255, 0, 0.1); background-color: rgba(255, 255, 0, 0.1);
@ -348,7 +330,7 @@ body[dir="rtl"] #vwRenderer .logEntry > div > span:first-child {
#vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(2), #vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(2),
#vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(3), #vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(3),
#vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(5) { #vwRenderer .logEntry > div.canDetails:hover > span:nth-of-type(5) {
background: rgba(0, 0, 0, 0.08); background: rgba(0, 0, 0, 0.1);
cursor: zoom-in; cursor: zoom-in;
} }
#netInspector:not(.vExpanded) #vwRenderer .logEntry > div > span:nth-of-type(4) { #netInspector:not(.vExpanded) #vwRenderer .logEntry > div > span:nth-of-type(4) {
@ -369,19 +351,6 @@ body[dir="rtl"] #vwRenderer .logEntry > div > span:first-child {
#vwRenderer .logEntry > div > span:nth-of-type(5) { #vwRenderer .logEntry > div > span:nth-of-type(5) {
position: relative; position: relative;
} }
#vwRenderer .logEntry > div[data-tabid="-1"] > span:nth-of-type(5)::before {
border: 5px solid #ccc;
border-bottom: 0;
border-top: 0;
bottom: 0;
content: '\00a0';
left: 0;
position: absolute;
right: 0;
top: 0;
width: calc(100% - 10px);
z-index: -1;
}
#vwRenderer .logEntry > div > span:nth-of-type(6) { #vwRenderer .logEntry > div > span:nth-of-type(6) {
} }
#vwRenderer #vwContent .logEntry > div > span:nth-of-type(6) { #vwRenderer #vwContent .logEntry > div > span:nth-of-type(6) {
@ -630,19 +599,15 @@ body[dir="rtl"] #netFilteringDialog > .headers > .tools {
border: 0; border: 0;
border-bottom: 1px solid white; border-bottom: 1px solid white;
display: flex; display: flex;
min-height: 2.2em;
} }
#netFilteringDialog > .panes > .details > div > span { #netFilteringDialog > .panes > .details > div > span {
align-items: center; padding: 0.5em;
display: inline-flex;
flex-wrap: wrap;
padding: 0.25em 0.5em;
} }
#netFilteringDialog > .panes > .details > div > span:nth-of-type(1) { #netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
border: 0; border: 0;
flex-grow: 0; flex-grow: 0;
flex-shrink: 0; flex-shrink: 0;
justify-content: flex-end; text-align: right;
width: 8em; width: 8em;
} }
body[dir="ltr"] #netFilteringDialog > .panes > .details > div > span:nth-of-type(1) { body[dir="ltr"] #netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
@ -875,6 +840,43 @@ body[dir="rtl"] #loggerSettingsDialog ul {
max-width: 6em; max-width: 6em;
} }
#loggerExportDialog {
display: flex;
flex-direction: column;
}
#loggerExportDialog .options {
display: flex;
justify-content: space-between;
margin-bottom: 1em;
}
#loggerExportDialog .options > div {
white-space: nowrap;
}
#loggerExportDialog .options span[data-i18n] {
border: 1px solid lightblue;
cursor: pointer;
font-size: 90%;
margin: 0 0.25em 0 0;
padding: 0.5em;
white-space: nowrap;
}
#loggerExportDialog .options span[data-i18n]:last-of-type {
margin: 0;
}
#loggerExportDialog .options span[data-i18n]:hover {
background-color: aliceblue;
}
#loggerExportDialog .options span.on[data-i18n],
#loggerExportDialog .options span.pushbutton:active {
background-color: lightblue;
}
#loggerExportDialog .output {
font: x-small mono;
height: 60vh;
padding: 0.5em;
white-space: pre;
}
.hide { .hide {
display: none !important; display: none !important;
} }

View File

@ -28,6 +28,7 @@ License - https://github.com/FortAwesome/Font-Awesome/tree/a8386aae19e200ddb0f68
<defs> <defs>
<symbol id="angle-up" viewBox="0 0 998 582"><path d="m 998,499 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 499,179 106,572 Q 96,582 83,582 70,582 60,572 L 10,522 Q 0,512 0,499 0,486 10,476 L 476,10 q 10,-10 23,-10 13,0 23,10 l 466,466 q 10,10 10,23 z"/></symbol> <symbol id="angle-up" viewBox="0 0 998 582"><path d="m 998,499 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 499,179 106,572 Q 96,582 83,582 70,582 60,572 L 10,522 Q 0,512 0,499 0,486 10,476 L 476,10 q 10,-10 23,-10 13,0 23,10 l 466,466 q 10,10 10,23 z"/></symbol>
<symbol id="bolt" viewBox="0 0 896 1664"><path d="m 885.08696,438 q 18,20 7,44 l -540,1157 q -13,25 -42,25 -4,0 -14,-2 -17,-5 -25.5,-19 -8.5,-14 -4.5,-30 l 197,-808 -406,101 q -4,1 -12,1 -18,0 -31,-11 Q -3.9130435,881 1.0869565,857 L 202.08696,32 q 4,-14 16,-23 12,-9 28,-9 l 328,0 q 19,0 32,12.5 13,12.5 13,29.5 0,8 -5,18 l -171,463 396,-98 q 8,-2 12,-2 19,0 34,15 z"/></symbol> <symbol id="bolt" viewBox="0 0 896 1664"><path d="m 885.08696,438 q 18,20 7,44 l -540,1157 q -13,25 -42,25 -4,0 -14,-2 -17,-5 -25.5,-19 -8.5,-14 -4.5,-30 l 197,-808 -406,101 q -4,1 -12,1 -18,0 -31,-11 Q -3.9130435,881 1.0869565,857 L 202.08696,32 q 4,-14 16,-23 12,-9 28,-9 l 328,0 q 19,0 32,12.5 13,12.5 13,29.5 0,8 -5,18 l -171,463 396,-98 q 8,-2 12,-2 19,0 34,15 z"/></symbol>
<symbol id="clipboard" viewBox="0 0 1792 1792"><path d="m 768,1664 896,0 0,-640 -416,0 q -40,0 -68,-28 -28,-28 -28,-68 l 0,-416 -384,0 0,1152 z m 256,-1440 0,-64 q 0,-13 -9.5,-22.5 Q 1005,128 992,128 l -704,0 q -13,0 -22.5,9.5 Q 256,147 256,160 l 0,64 q 0,13 9.5,22.5 9.5,9.5 22.5,9.5 l 704,0 q 13,0 22.5,-9.5 9.5,-9.5 9.5,-22.5 z m 256,672 299,0 -299,-299 0,299 z m 512,128 0,672 q 0,40 -28,68 -28,28 -68,28 l -960,0 q -40,0 -68,-28 -28,-28 -28,-68 l 0,-160 -544,0 Q 56,1536 28,1508 0,1480 0,1440 L 0,96 Q 0,56 28,28 56,0 96,0 l 1088,0 q 40,0 68,28 28,28 28,68 l 0,328 q 21,13 36,28 l 408,408 q 28,28 48,76 20,48 20,88 z"/></symbol>
<symbol id="code" viewBox="0 0 1830 1373"><path d="m 572,1125.5 -50,50 q -10,10 -23,10 -13,0 -23,-10 l -466,-466 q -10,-10 -10,-23 0,-13 10,-23 l 466,-466 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 l -393,393 393,393 q 10,10 10,23 0,13 -10,23 z M 1163,58.476203 790,1349.4762 q -4,13 -15.5,19.5 -11.5,6.5 -23.5,2.5 l -62,-17 q -13,-4 -19.5,-15.5 -6.5,-11.5 -2.5,-24.5 L 1040,23.5 q 4,-13 15.5,-19.5 11.5,-6.5 23.5,-2.5 l 62,17 q 13,4 19.5,15.5 6.5,11.5 2.5,24.5 z m 657,651 -466,466 q -10,10 -23,10 -13,0 -23,-10 l -50,-50 q -10,-10 -10,-23 0,-13 10,-23 l 393,-393 -393,-393 q -10,-10 -10,-23 0,-13 10,-23 l 50,-50 q 10,-10 23,-10 13,0 23,10 l 466,466 q 10,10 10,23 0,13 -10,23 z"/></symbol> <symbol id="code" viewBox="0 0 1830 1373"><path d="m 572,1125.5 -50,50 q -10,10 -23,10 -13,0 -23,-10 l -466,-466 q -10,-10 -10,-23 0,-13 10,-23 l 466,-466 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 l -393,393 393,393 q 10,10 10,23 0,13 -10,23 z M 1163,58.476203 790,1349.4762 q -4,13 -15.5,19.5 -11.5,6.5 -23.5,2.5 l -62,-17 q -13,-4 -19.5,-15.5 -6.5,-11.5 -2.5,-24.5 L 1040,23.5 q 4,-13 15.5,-19.5 11.5,-6.5 23.5,-2.5 l 62,17 q 13,4 19.5,15.5 6.5,11.5 2.5,24.5 z m 657,651 -466,466 q -10,10 -23,10 -13,0 -23,-10 l -50,-50 q -10,-10 -10,-23 0,-13 10,-23 l 393,-393 -393,-393 q -10,-10 -10,-23 0,-13 10,-23 l 50,-50 q 10,-10 23,-10 13,0 23,10 l 466,466 q 10,10 10,23 0,13 -10,23 z"/></symbol>
<symbol id="cog" viewBox="0 0 1536 1536"><path d="m 1024,768 q 0,-106 -75,-181 -75,-75 -181,-75 -106,0 -181,75 -75,75 -75,181 0,106 75,181 75,75 181,75 106,0 181,-75 75,-75 75,-181 z m 512,-109 0,222 q 0,12 -8,23 -8,11 -20,13 l -185,28 q -19,54 -39,91 35,50 107,138 10,12 10,25 0,13 -9,23 -27,37 -99,108 -72,71 -94,71 -12,0 -26,-9 l -138,-108 q -44,23 -91,38 -16,136 -29,186 -7,28 -36,28 l -222,0 q -14,0 -24.5,-8.5 Q 622,1519 621,1506 l -28,-184 q -49,-16 -90,-37 l -141,107 q -10,9 -25,9 -14,0 -25,-11 -126,-114 -165,-168 -7,-10 -7,-23 0,-12 8,-23 15,-21 51,-66.5 36,-45.5 54,-70.5 -27,-50 -41,-99 L 29,913 Q 16,911 8,900.5 0,890 0,877 L 0,655 q 0,-12 8,-23 8,-11 19,-13 l 186,-28 q 14,-46 39,-92 -40,-57 -107,-138 -10,-12 -10,-24 0,-10 9,-23 26,-36 98.5,-107.5 Q 315,135 337,135 q 13,0 26,10 L 501,252 Q 545,229 592,214 608,78 621,28 628,0 657,0 L 879,0 Q 893,0 903.5,8.5 914,17 915,30 l 28,184 q 49,16 90,37 l 142,-107 q 9,-9 24,-9 13,0 25,10 129,119 165,170 7,8 7,22 0,12 -8,23 -15,21 -51,66.5 -36,45.5 -54,70.5 26,50 41,98 l 183,28 q 13,2 21,12.5 8,10.5 8,23.5 z"/></symbol> <symbol id="cog" viewBox="0 0 1536 1536"><path d="m 1024,768 q 0,-106 -75,-181 -75,-75 -181,-75 -106,0 -181,75 -75,75 -75,181 0,106 75,181 75,75 181,75 106,0 181,-75 75,-75 75,-181 z m 512,-109 0,222 q 0,12 -8,23 -8,11 -20,13 l -185,28 q -19,54 -39,91 35,50 107,138 10,12 10,25 0,13 -9,23 -27,37 -99,108 -72,71 -94,71 -12,0 -26,-9 l -138,-108 q -44,23 -91,38 -16,136 -29,186 -7,28 -36,28 l -222,0 q -14,0 -24.5,-8.5 Q 622,1519 621,1506 l -28,-184 q -49,-16 -90,-37 l -141,107 q -10,9 -25,9 -14,0 -25,-11 -126,-114 -165,-168 -7,-10 -7,-23 0,-12 8,-23 15,-21 51,-66.5 36,-45.5 54,-70.5 -27,-50 -41,-99 L 29,913 Q 16,911 8,900.5 0,890 0,877 L 0,655 q 0,-12 8,-23 8,-11 19,-13 l 186,-28 q 14,-46 39,-92 -40,-57 -107,-138 -10,-12 -10,-24 0,-10 9,-23 26,-36 98.5,-107.5 Q 315,135 337,135 q 13,0 26,10 L 501,252 Q 545,229 592,214 608,78 621,28 628,0 657,0 L 879,0 Q 893,0 903.5,8.5 914,17 915,30 l 28,184 q 49,16 90,37 l 142,-107 q 9,-9 24,-9 13,0 25,10 129,119 165,170 7,8 7,22 0,12 -8,23 -15,21 -51,66.5 -36,45.5 -54,70.5 26,50 41,98 l 183,28 q 13,2 21,12.5 8,10.5 8,23.5 z"/></symbol>
<symbol id="double-angle-left" viewBox="0 0 966 998"><path d="m 582,915 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 10,522 Q 0,512 0,499 0,486 10,476 L 476,10 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 L 179,499 572,892 q 10,10 10,23 z m 384,0 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 394,522 q -10,-10 -10,-23 0,-13 10,-23 L 860,10 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 L 563,499 956,892 q 10,10 10,23 z"/></symbol> <symbol id="double-angle-left" viewBox="0 0 966 998"><path d="m 582,915 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 10,522 Q 0,512 0,499 0,486 10,476 L 476,10 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 L 179,499 572,892 q 10,10 10,23 z m 384,0 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 394,522 q -10,-10 -10,-23 0,-13 10,-23 L 860,10 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 0,13 -10,23 L 563,499 956,892 q 10,10 10,23 z"/></symbol>

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -341,6 +341,9 @@ const parseLogEntry = function(details) {
) { ) {
let partyness = ''; let partyness = '';
if ( entry.tabDomain !== undefined ) { if ( entry.tabDomain !== undefined ) {
if ( entry.tabId < 0 ) {
partyness += '0,';
}
partyness += entry.domain === entry.tabDomain ? '1' : '3'; partyness += entry.domain === entry.tabDomain ? '1' : '3';
} else { } else {
partyness += '?'; partyness += '?';
@ -1041,7 +1044,7 @@ const reloadTab = function(ev) {
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/
const netFilteringManager = (function() { (function() {
const reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/; const reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
const staticFilterTypes = { const staticFilterTypes = {
'beacon': 'other', 'beacon': 'other',
@ -1400,11 +1403,11 @@ const netFilteringManager = (function() {
return urls; return urls;
}; };
const fillSummaryPaneFilterList = function(row) { const fillSummaryPaneFilterList = function(rows) {
const rawFilter = targetRow.children[1].textContent;
const compiledFilter = targetRow.getAttribute('data-filter');
const nodeFromFilter = function(filter, lists) { const nodeFromFilter = function(filter, lists) {
if ( Array.isArray(lists) === false || lists.length === 0 ) {
return;
}
const fragment = document.createDocumentFragment(); const fragment = document.createDocumentFragment();
const template = document.querySelector( const template = document.querySelector(
'#filterFinderListEntry > span' '#filterFinderListEntry > span'
@ -1414,9 +1417,11 @@ const netFilteringManager = (function() {
let a = span.querySelector('a:nth-of-type(1)'); let a = span.querySelector('a:nth-of-type(1)');
a.href += encodeURIComponent(list.assetKey); a.href += encodeURIComponent(list.assetKey);
a.textContent = list.title; a.textContent = list.title;
a = span.querySelector('a:nth-of-type(2)');
if ( list.supportURL ) { if ( list.supportURL ) {
a = span.querySelector('a:nth-of-type(2)');
a.setAttribute('href', list.supportURL); a.setAttribute('href', list.supportURL);
} else {
a.style.display = 'none';
} }
if ( fragment.childElementCount !== 0 ) { if ( fragment.childElementCount !== 0 ) {
fragment.appendChild(document.createTextNode('\n')); fragment.appendChild(document.createTextNode('\n'));
@ -1430,24 +1435,31 @@ const netFilteringManager = (function() {
if ( response instanceof Object === false ) { if ( response instanceof Object === false ) {
response = {}; response = {};
} }
const fragment = document.createDocumentFragment(); let bestMatchFilter = '';
for ( const filter in response ) { for ( const filter in response ) {
const spans = nodeFromFilter(filter, response[filter]); if ( filter.length > bestMatchFilter.length ) {
if ( spans === undefined ) { continue; } bestMatchFilter = filter;
fragment.appendChild(spans); }
}
if (
bestMatchFilter !== '' &&
Array.isArray(response[bestMatchFilter])
) {
rows[0].children[1].textContent = bestMatchFilter;
rows[1].children[1].appendChild(nodeFromFilter(
bestMatchFilter,
response[bestMatchFilter]
));
} }
row.children[1].appendChild(fragment);
// https://github.com/gorhill/uBlock/issues/2179 // https://github.com/gorhill/uBlock/issues/2179
if ( row.children[1].childElementCount === 0 ) { if ( rows[1].children[1].childElementCount === 0 ) {
vAPI.i18n.safeTemplateToDOM( vAPI.i18n.safeTemplateToDOM(
'loggerStaticFilteringFinderSentence2', 'loggerStaticFilteringFinderSentence2',
{ filter: rawFilter }, { filter: rawFilter },
row.children[1] rows[1].children[1]
); );
} }
}; };
const rawFilter = targetRow.children[1].textContent;
const compiledFilter = targetRow.getAttribute('data-filter');
if ( targetRow.classList.contains('networkRealm') ) { if ( targetRow.classList.contains('networkRealm') ) {
messaging.send( messaging.send(
@ -1499,7 +1511,7 @@ const netFilteringManager = (function() {
} }
// Filter list // Filter list
if ( trcl.contains('canLookup') ) { if ( trcl.contains('canLookup') ) {
fillSummaryPaneFilterList(rows[1]); fillSummaryPaneFilterList(rows);
} else { } else {
rows[1].style.display = 'none'; rows[1].style.display = 'none';
} }
@ -1519,7 +1531,7 @@ const netFilteringManager = (function() {
// Partyness // Partyness
text = tr.getAttribute('data-parties') || ''; text = tr.getAttribute('data-parties') || '';
if ( text !== '' ) { if ( text !== '' ) {
rows[5].children[1].textContent = `${trch[4].textContent}\u2002${text}`; rows[5].children[1].textContent = `(${trch[4].textContent})\u2002${text}`;
} else { } else {
rows[5].style.display = 'none'; rows[5].style.display = 'none';
} }
@ -1738,7 +1750,11 @@ const netFilteringManager = (function() {
); );
}; };
return { toggleOn }; uDom('#netInspector').on(
'click',
'.canDetails > span:nth-of-type(2),.canDetails > span:nth-of-type(3),.canDetails > span:nth-of-type(5)',
toggleOn
);
})(); })();
// https://www.youtube.com/watch?v=XyNYrmmdUd4 // https://www.youtube.com/watch?v=XyNYrmmdUd4
@ -2255,6 +2271,187 @@ const popupManager = (function() {
/******************************************************************************/ /******************************************************************************/
(function() {
const lines = [];
const options = {
format: 'list',
encoding: 'markdown',
time: 'anonymous',
};
let dialog;
const collectLines = function() {
lines.length = 0;
let t0 = filteredLoggerEntries.length !== 0
? filteredLoggerEntries[filteredLoggerEntries.length - 1].tstamp
: 0;
for ( const entry of filteredLoggerEntries ) {
const text = entry.textContent;
const fields = [];
let i = 0;
let beg = text.indexOf('\t');
if ( beg === 0 ) { continue; }
let timeField = text.slice(0, beg);
if ( options.time === 'anonymous' ) {
timeField = '+' + Math.round((entry.tstamp - t0) / 1000).toString();
}
fields.push(timeField);
beg += 1;
while ( beg < text.length ) {
let end = text.indexOf('\t', beg);
if ( end === -1 ) { end = text.length; }
fields.push(text.slice(beg, end));
beg = end + 1;
i += 1;
}
lines.push(fields);
}
};
const formatAsPlainTextTable = function() {
const outputAll = [];
for ( const fields of lines ) {
outputAll.push(fields.join('\t'));
}
outputAll.push('');
return outputAll.join('\n');
};
const formatAsMarkdownTable = function() {
const outputAll = [];
let fieldCount = 0;
for ( const fields of lines ) {
if ( fields.length <= 2 ) { continue; }
if ( fields.length > fieldCount ) {
fieldCount = fields.length;
}
const outputOne = [];
for ( let i = 0; i < fields.length; i++ ) {
const field = fields[i];
let code = /\b(?:www\.|https?:\/\/)/.test(field) ? '`' : '';
outputOne.push(` ${code}${field.replace(/\|/g, '\\|')}${code} `);
}
outputAll.push(outputOne.join('|'));
}
outputAll.unshift(
`${' |'.repeat(fieldCount-1)} `,
`${':--- |'.repeat(fieldCount-1)}:--- `
);
return `<details><summary>Logger output</summary>\n\n|${outputAll.join('|\n|')}|\n</details>\n`;
};
const formatAsTable = function() {
if ( options.encoding === 'plain' ) {
return formatAsPlainTextTable();
}
return formatAsMarkdownTable();
};
const formatAsList = function() {
const outputAll = [];
for ( const fields of lines ) {
const outputOne = [];
for ( let i = 0; i < fields.length; i++ ) {
let str = fields[i];
if ( str.length === 0 ) { continue; }
outputOne.push(str);
}
outputAll.push(outputOne.join('\n'));
}
let before, between, after;
if ( options.encoding === 'markdown' ) {
const code = '```';
before = `<details><summary>Logger output</summary>\n\n${code}\n`;
between = `\n${code}\n${code}\n`;
after = `\n${code}\n</details>\n`;
} else {
before = '';
between = '\n\n';
after = '\n';
}
return `${before}${outputAll.join(between)}${after}`;
};
const format = function() {
const output = dialog.querySelector('.output');
if ( options.format === 'list' ) {
output.textContent = formatAsList();
} else {
output.textContent = formatAsTable();
}
};
const setRadioButton = function(group, value) {
if ( options.hasOwnProperty(group) === false ) { return; }
const groupEl = dialog.querySelector(`[data-radio="${group}"]`);
const buttonEls = groupEl.querySelectorAll('[data-radio-item]');
for ( const buttonEl of buttonEls ) {
buttonEl.classList.toggle(
'on',
buttonEl.getAttribute('data-radio-item') === value
);
}
options[group] = value;
format();
};
const onOption = function(ev) {
const target = ev.target.closest('span[data-i18n]');
if ( target === null ) { return; }
// Copy to clipboard
if ( target.matches('.pushbutton') ) {
const textarea = dialog.querySelector('textarea');
textarea.focus();
if ( textarea.selectionEnd === textarea.selectionStart ) {
textarea.select();
}
document.execCommand('copy');
ev.stopPropagation();
return;
}
// Radio buttons
const group = target.closest('[data-radio]');
if ( group === null ) { return; }
if ( target.matches('span.on') ) { return; }
const item = target.closest('[data-radio-item]');
if ( item === null ) { return; }
setRadioButton(
group.getAttribute('data-radio'),
item.getAttribute('data-radio-item')
);
ev.stopPropagation();
};
const toggleOn = function() {
dialog = modalDialog.create(
'#loggerExportDialog',
( ) => {
dialog = undefined;
lines.length = 0;
}
);
setRadioButton('format', options.format);
setRadioButton('encoding', options.encoding);
dialog.querySelector('.options').addEventListener(
'click',
onOption,
{ capture: true }
);
collectLines();
format();
modalDialog.show();
};
uDom.nodeFromId('loggerExport').addEventListener('click', toggleOn);
})();
/******************************************************************************/
// TODO: // TODO:
// - Give some thoughts to: // - Give some thoughts to:
// - an option to discard immediately filtered out new entries // - an option to discard immediately filtered out new entries
@ -2429,16 +2626,9 @@ window.addEventListener('beforeunload', releaseView);
uDom('#pageSelector').on('change', pageSelectorChanged); uDom('#pageSelector').on('change', pageSelectorChanged);
uDom('#refresh').on('click', reloadTab); uDom('#refresh').on('click', reloadTab);
uDom('#netInspector .vCompactToggler').on('click', toggleVCompactView); uDom('#netInspector .vCompactToggler').on('click', toggleVCompactView);
uDom('#pause').on('click', pauseNetInspector); uDom('#pause').on('click', pauseNetInspector);
uDom('#netInspector').on(
'click',
'span:nth-of-type(2),span:nth-of-type(3),span:nth-of-type(5)',
netFilteringManager.toggleOn
);
// https://github.com/gorhill/uBlock/issues/507 // https://github.com/gorhill/uBlock/issues/507
// Ensure tab selector is in sync with URL hash // Ensure tab selector is in sync with URL hash
pageSelectorFromURLHash(); pageSelectorFromURLHash();

View File

@ -25,18 +25,18 @@
/******************************************************************************/ /******************************************************************************/
var listEntries = Object.create(null), const reBlockStart = /^#block-start-(\d+)\n/gm;
reBlockStart = /^#block-start-(\d+)\n/gm; let listEntries = Object.create(null);
/******************************************************************************/ /******************************************************************************/
var extractBlocks = function(content, begId, endId) { const extractBlocks = function(content, begId, endId) {
reBlockStart.lastIndex = 0; reBlockStart.lastIndex = 0;
var out = []; const out = [];
var match = reBlockStart.exec(content); let match = reBlockStart.exec(content);
while ( match !== null ) { while ( match !== null ) {
var beg = match.index + match[0].length; const beg = match.index + match[0].length;
var blockId = parseInt(match[1], 10); const blockId = parseInt(match[1], 10);
if ( blockId >= begId && blockId < endId ) { if ( blockId >= begId && blockId < endId ) {
var end = content.indexOf('#block-end-' + match[1], beg); var end = content.indexOf('#block-end-' + match[1], beg);
out.push(content.slice(beg, end)); out.push(content.slice(beg, end));
@ -49,14 +49,14 @@ var extractBlocks = function(content, begId, endId) {
/******************************************************************************/ /******************************************************************************/
var fromNetFilter = function(details) { const fromNetFilter = function(details) {
var lists = [], const lists = [];
compiledFilter = details.compiledFilter; const compiledFilter = details.compiledFilter;
for ( let assetKey in listEntries ) { for ( const assetKey in listEntries ) {
let entry = listEntries[assetKey]; const entry = listEntries[assetKey];
if ( entry === undefined ) { continue; } if ( entry === undefined ) { continue; }
let content = extractBlocks(entry.content, 0, 1000); const content = extractBlocks(entry.content, 0, 1000);
let pos = 0; let pos = 0;
for (;;) { for (;;) {
pos = content.indexOf(compiledFilter, pos); pos = content.indexOf(compiledFilter, pos);
@ -64,7 +64,7 @@ var fromNetFilter = function(details) {
// We need an exact match. // We need an exact match.
// https://github.com/gorhill/uBlock/issues/1392 // https://github.com/gorhill/uBlock/issues/1392
// https://github.com/gorhill/uBlock/issues/835 // https://github.com/gorhill/uBlock/issues/835
let notFound = pos !== 0 && content.charCodeAt(pos - 1) !== 0x0A; const notFound = pos !== 0 && content.charCodeAt(pos - 1) !== 0x0A;
pos += compiledFilter.length; pos += compiledFilter.length;
if ( if (
notFound || notFound ||
@ -81,7 +81,7 @@ var fromNetFilter = function(details) {
} }
} }
let response = {}; const response = {};
response[details.rawFilter] = lists; response[details.rawFilter] = lists;
postMessage({ postMessage({
@ -112,18 +112,18 @@ var fromNetFilter = function(details) {
// FilterContainer.fromCompiledContent() is our reference code to create // FilterContainer.fromCompiledContent() is our reference code to create
// the various compiled versions. // the various compiled versions.
let fromCosmeticFilter = function(details) { const fromCosmeticFilter = function(details) {
let match = /^#@?#\^?/.exec(details.rawFilter), const match = /^#@?#\^?/.exec(details.rawFilter);
prefix = match[0], const prefix = match[0];
exception = prefix.charAt(1) === '@', const exception = prefix.charAt(1) === '@';
selector = details.rawFilter.slice(prefix.length); const selector = details.rawFilter.slice(prefix.length);
// The longer the needle, the lower the number of false positives. // The longer the needle, the lower the number of false positives.
let needle = selector.match(/\w+/g).reduce(function(a, b) { const needle = selector.match(/\w+/g).reduce(function(a, b) {
return a.length > b.length ? a : b; return a.length > b.length ? a : b;
}); });
let reHostname = new RegExp( const reHostname = new RegExp(
'^' + '^' +
details.hostname.split('.').reduce( details.hostname.split('.').reduce(
function(acc, item) { function(acc, item) {
@ -154,16 +154,16 @@ let fromCosmeticFilter = function(details) {
); );
} }
let hostnameMatches = hn => { const hostnameMatches = hn => {
return hn === '' || return hn === '' ||
reHostname.test(hn) || reHostname.test(hn) ||
reEntity !== undefined && reEntity.test(hn); reEntity !== undefined && reEntity.test(hn);
}; };
let response = Object.create(null); const response = Object.create(null);
for ( let assetKey in listEntries ) { for ( const assetKey in listEntries ) {
let entry = listEntries[assetKey]; const entry = listEntries[assetKey];
if ( entry === undefined ) { continue; } if ( entry === undefined ) { continue; }
let content = extractBlocks(entry.content, 1000, 2000), let content = extractBlocks(entry.content, 1000, 2000),
isProcedural, isProcedural,
@ -274,7 +274,7 @@ let fromCosmeticFilter = function(details) {
/******************************************************************************/ /******************************************************************************/
onmessage = function(e) { // jshint ignore:line onmessage = function(e) { // jshint ignore:line
var msg = e.data; const msg = e.data;
switch ( msg.what ) { switch ( msg.what ) {
case 'resetLists': case 'resetLists':

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2018 Raymond Hill Copyright (C) 2014-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -32,11 +32,11 @@
// the code here does *only* what I need, and nothing more, and with a lot // 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. // of assumption on passed parameters, etc. I grow it on a per-need-basis only.
var uDom = (function() { const uDom = (function() {
/******************************************************************************/ /******************************************************************************/
var DOMList = function() { const DOMList = function() {
this.nodes = []; this.nodes = [];
}; };
@ -54,7 +54,7 @@ Object.defineProperty(
/******************************************************************************/ /******************************************************************************/
var DOMListFactory = function(selector, context) { const DOMListFactory = function(selector, context) {
var r = new DOMList(); var r = new DOMList();
if ( typeof selector === 'string' ) { if ( typeof selector === 'string' ) {
selector = selector.trim(); selector = selector.trim();
@ -92,7 +92,7 @@ DOMListFactory.nodeFromSelector = function(selector) {
/******************************************************************************/ /******************************************************************************/
var addNodeToList = function(list, node) { const addNodeToList = function(list, node) {
if ( node ) { if ( node ) {
list.nodes.push(node); list.nodes.push(node);
} }
@ -101,7 +101,7 @@ var addNodeToList = function(list, node) {
/******************************************************************************/ /******************************************************************************/
var addNodeListToList = function(list, nodelist) { const addNodeListToList = function(list, nodelist) {
if ( nodelist ) { if ( nodelist ) {
var n = nodelist.length; var n = nodelist.length;
for ( var i = 0; i < n; i++ ) { for ( var i = 0; i < n; i++ ) {
@ -113,14 +113,14 @@ var addNodeListToList = function(list, nodelist) {
/******************************************************************************/ /******************************************************************************/
var addListToList = function(list, other) { const addListToList = function(list, other) {
list.nodes = list.nodes.concat(other.nodes); list.nodes = list.nodes.concat(other.nodes);
return list; return list;
}; };
/******************************************************************************/ /******************************************************************************/
var addSelectorToList = function(list, selector, context) { const addSelectorToList = function(list, selector, context) {
var p = context || document; var p = context || document;
var r = p.querySelectorAll(selector); var r = p.querySelectorAll(selector);
var n = r.length; var n = r.length;
@ -132,15 +132,6 @@ var addSelectorToList = function(list, selector, context) {
/******************************************************************************/ /******************************************************************************/
const nodeInNodeList = function(node, nodeList) {
for ( const other of nodeList ) {
if ( other === node ) { return true; }
}
return false;
};
/******************************************************************************/
DOMList.prototype.nodeAt = function(i) { DOMList.prototype.nodeAt = function(i) {
return this.nodes[i] || null; return this.nodes[i] || null;
}; };
@ -526,7 +517,7 @@ DOMList.prototype.text = function(text) {
/******************************************************************************/ /******************************************************************************/
var toggleClass = function(node, className, targetState) { const toggleClass = function(node, className, targetState) {
var tokenList = node.classList; var tokenList = node.classList;
if ( tokenList instanceof DOMTokenList === false ) { if ( tokenList instanceof DOMTokenList === false ) {
return; return;
@ -628,7 +619,12 @@ const makeEventHandler = function(selector, callback) {
return; return;
} }
const receiver = event.target; const receiver = event.target;
if ( nodeInNodeList(receiver, dispatcher.querySelectorAll(selector)) ) { const ancestor = receiver.closest(selector);
if (
ancestor !== null &&
ancestor !== dispatcher &&
dispatcher.contains(ancestor)
) {
callback.call(receiver, event); callback.call(receiver, event);
} }
}; };
@ -678,7 +674,7 @@ DOMList.prototype.trigger = function(etype) {
// Cleanup // Cleanup
var onBeforeUnload = function() { const onBeforeUnload = function() {
var entry; var entry;
while ( (entry = listenerEntries.pop()) ) { while ( (entry = listenerEntries.pop()) ) {
entry.dispose(); entry.dispose();

View File

@ -14,15 +14,19 @@
<body> <body>
<div class="permatoolbar"> <div class="permatoolbar">
<select id="pageSelector"> <div>
<option value="0" data-i18n="logAll"> <select id="pageSelector">
<option value="-1" data-i18n="logBehindTheScene"> <option value="0" data-i18n="logAll">
<option value="_" data-i18n="loggerCurrentTab"> <option value="-1" data-i18n="logBehindTheScene">
</select> <option value="_" data-i18n="loggerCurrentTab">
<span id="refresh" class="button fa-icon disabled needdom" data-i18n-title="loggerReloadTip">refresh</span> </select>
<span id="showdom" class="button fa-icon disabled needdom" data-i18n-title="loggerDomInspectorTip">code</span> <span id="refresh" class="button fa-icon disabled needdom" data-i18n-title="loggerReloadTip">refresh</span>
<span id="showpopup" class="button ubo-icon disabled needdom" data-i18n-title="loggerPopupPanelTip"><svg><use href="/img/ublock-defs.svg#ubo-solid"></use></svg></span> <span id="showdom" class="button fa-icon disabled needdom" data-i18n-title="loggerDomInspectorTip">code</span>
<a id="info" class="button fa-icon" href="https://github.com/gorhill/uBlock/wiki/The-logger" target="_blank" data-i18n-title="loggerInfoTip">info-circle</a> <span id="showpopup" class="button ubo-icon disabled needdom" data-i18n-title="loggerPopupPanelTip"><svg><use href="/img/ublock-defs.svg#ubo-solid"></use></svg></span>
</div>
<div>
<a id="info" class="button fa-icon" href="https://github.com/gorhill/uBlock/wiki/The-logger" target="_blank" data-i18n-title="loggerInfoTip">info-circle</a>
</div>
</div> </div>
<div id="inspectors"> <div id="inspectors">
@ -42,23 +46,28 @@
</div> </div>
<div id="netInspector" class="inspector f"> <div id="netInspector" class="inspector f">
<div class="permatoolbar"> <div class="permatoolbar">
<span class="button fa-icon vCompactToggler">double-angle-up</span> <div>
<span id="clean" class="button fa-icon disabled">times</span> <span class="button fa-icon vCompactToggler">double-angle-up</span>
<span id="clear" class="button fa-icon disabled" data-i18n-title="loggerClearTip">eraser</span> <span id="clean" class="button fa-icon disabled">times</span>
<span id="pause"><span class="button fa-icon" data-i18n-title="loggerPauseTip">pause-circle-o</span><span class="button fa-icon" data-i18n-title="loggerUnpauseTip">play-circle-o</span></span> <span id="clear" class="button fa-icon disabled" data-i18n-title="loggerClearTip">eraser</span>
<span id="filterExprGroup"> <span id="pause"><span class="button fa-icon" data-i18n-title="loggerPauseTip">pause-circle-o</span><span class="button fa-icon" data-i18n-title="loggerUnpauseTip">play-circle-o</span></span>
<span id="filterButton" class="button fa-icon" data-i18n-title="loggerRowFiltererButtonTip">filter</span> <span id="filterExprGroup">
<span id="filterInput"> <span id="filterButton" class="button fa-icon" data-i18n-title="loggerRowFiltererButtonTip">filter</span>
<input type="text" placeholder="logFilterPrompt"> <span id="filterInput">
<span id="filterExprButton" class="button fa-icon expanded" data-i18n-title="loggerRowFiltererBuiltinTip">angle-up</span> <input type="text" placeholder="logFilterPrompt">
<div id="filterExprPicker"> <span id="filterExprButton" class="button fa-icon expanded" data-i18n-title="loggerRowFiltererBuiltinTip">angle-up</span>
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t--\t|\t<<\t|\t##" data-i18n="loggerRowFiltererBuiltinBlocked"></span><span data-filtex="\t\+\+\t|\t\*\*\t|\t#@#" data-i18n="loggerRowFiltererBuiltinAllowed"></span></div> <div id="filterExprPicker">
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t(?:css|font)\t">css/font</span><span data-filtex="\timage\t">image</span><span data-filtex="\t(?:inline-)?script(?:ing)?\t">script</span><span data-filtex="\t(?:websocket|xhr)\t">xhr</span><span data-filtex="\tframe\t">frame</span><span data-filtex="\tdom\t">dom</span></div> <div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t--\t|\t<<\t|\t##" data-i18n="loggerRowFiltererBuiltinBlocked"></span><span data-filtex="\t\+\+\t|\t\*\*\t|\t#@#" data-i18n="loggerRowFiltererBuiltinAllowed"></span></div>
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t1\t" data-i18n="loggerRowFiltererBuiltin1p"></span><span data-filtex="\t3(?:,\d)?\t" data-i18n="loggerRowFiltererBuiltin3p"></span></div> <div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t(?:css|font)\t">css/font</span><span data-filtex="\timage\t">image</span><span data-filtex="\t(?:inline-)?script(?:ing)?\t">script</span><span data-filtex="\t(?:websocket|xhr)\t">xhr</span><span data-filtex="\tframe\t">frame</span><span data-filtex="\tdom\t">dom</span></div>
</div> <div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t(?:0,)?1\t" data-i18n="loggerRowFiltererBuiltin1p"></span><span data-filtex="\t(?:3(?:,\d)?|0,3)\t" data-i18n="loggerRowFiltererBuiltin3p"></span></div>
</div>
</span>
</span> </span>
</span> </div>
<span id="settings" class="button fa-icon">cog</span> <div>
<span id="loggerExport" class="button fa-icon">clipboard</span>
<span id="settings" class="button fa-icon">cog</span>
</div>
</div> </div>
<div class="vscrollable"> <div class="vscrollable">
<div id="vwRenderer"> <div id="vwRenderer">
@ -162,7 +171,24 @@
</ul> </ul>
</div> </div>
<div><label data-i18n="loggerSettingPerEntryLineCount"><input type="number" min="2" max="6"></label></div> <div><label data-i18n="loggerSettingPerEntryLineCount"><input type="number" min="2" max="6"></label></div>
</div>
<div id="loggerExportDialog">
<div class="options">
<div data-radio="format">
<span data-i18n="" data-radio-item="list">List</span>
<span data-i18n="" data-radio-item="table">Table</span>
</div>
<div data-radio="encoding">
<span data-i18n="" data-radio-item="plain">Plain</span>
<span data-i18n="" data-radio-item="markdown">Markdown</span>
</div>
<div>
<span data-i18n="" class="pushbutton">Copy to clipboard</span>
</div>
</div> </div>
<textarea class="output" readonly spellcheck="false"></textarea>
</div>
</div> </div>
<script src="js/fa-icons.js"></script> <script src="js/fa-icons.js"></script>