mirror of https://github.com/gorhill/uBlock.git
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:
parent
88a54d442d
commit
0edf53f508
|
@ -300,7 +300,7 @@
|
|||
"description": ""
|
||||
},
|
||||
"settingsNoLargeMediaPrompt":{
|
||||
"message":"Block media elements larger than {{input}} kB",
|
||||
"message":"Block media elements larger than {{input}} KB",
|
||||
"description": ""
|
||||
},
|
||||
"settingsNoRemoteFontsPrompt":{
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
.fa-icon > .fa-icon_exclamation-triangle {
|
||||
width: calc(1em * 1794 / 1792);
|
||||
}
|
||||
.fa-icon > .fa-icon_clipboard,
|
||||
.fa-icon > .fa-icon_eye-dropper,
|
||||
.fa-icon > .fa-icon_eye-slash,
|
||||
.fa-icon > .fa-icon_files-o,
|
||||
|
|
|
@ -23,8 +23,12 @@ textarea {
|
|||
display: flex;
|
||||
flex-shrink: 0;
|
||||
font-size: 120%;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
padding: 0.25em 0.5em;
|
||||
padding: 0.25em;
|
||||
}
|
||||
.permatoolbar > div {
|
||||
display: flex;
|
||||
}
|
||||
.permatoolbar .button {
|
||||
cursor: pointer;
|
||||
|
@ -59,24 +63,10 @@ body[dir="rtl"] #pageSelector {
|
|||
}
|
||||
#info {
|
||||
fill: #ccc;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
position: absolute;
|
||||
}
|
||||
#info:hover {
|
||||
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
|
||||
|
@ -204,17 +194,6 @@ body[dir="rtl"] #netInspector #filterExprPicker {
|
|||
background-color: 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 {
|
||||
overflow: hidden;
|
||||
|
@ -278,6 +257,9 @@ body.colorBlind #vwRenderer .logEntry > div[data-status="2"],
|
|||
body.colorBlind #netFilteringDialog > .panes > .details > div[data-status="2"] {
|
||||
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.redirect {
|
||||
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(3),
|
||||
#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;
|
||||
}
|
||||
#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) {
|
||||
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 #vwContent .logEntry > div > span:nth-of-type(6) {
|
||||
|
@ -630,19 +599,15 @@ body[dir="rtl"] #netFilteringDialog > .headers > .tools {
|
|||
border: 0;
|
||||
border-bottom: 1px solid white;
|
||||
display: flex;
|
||||
min-height: 2.2em;
|
||||
}
|
||||
#netFilteringDialog > .panes > .details > div > span {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.25em 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
#netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
|
||||
border: 0;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
justify-content: flex-end;
|
||||
text-align: right;
|
||||
width: 8em;
|
||||
}
|
||||
body[dir="ltr"] #netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
|
||||
|
@ -875,6 +840,43 @@ body[dir="rtl"] #loggerSettingsDialog ul {
|
|||
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 {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ License - https://github.com/FortAwesome/Font-Awesome/tree/a8386aae19e200ddb0f68
|
|||
<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="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="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>
|
||||
|
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
@ -341,6 +341,9 @@ const parseLogEntry = function(details) {
|
|||
) {
|
||||
let partyness = '';
|
||||
if ( entry.tabDomain !== undefined ) {
|
||||
if ( entry.tabId < 0 ) {
|
||||
partyness += '0,';
|
||||
}
|
||||
partyness += entry.domain === entry.tabDomain ? '1' : '3';
|
||||
} else {
|
||||
partyness += '?';
|
||||
|
@ -1041,7 +1044,7 @@ const reloadTab = function(ev) {
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
const netFilteringManager = (function() {
|
||||
(function() {
|
||||
const reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
||||
const staticFilterTypes = {
|
||||
'beacon': 'other',
|
||||
|
@ -1400,11 +1403,11 @@ const netFilteringManager = (function() {
|
|||
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) {
|
||||
if ( Array.isArray(lists) === false || lists.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
const fragment = document.createDocumentFragment();
|
||||
const template = document.querySelector(
|
||||
'#filterFinderListEntry > span'
|
||||
|
@ -1414,9 +1417,11 @@ const netFilteringManager = (function() {
|
|||
let a = span.querySelector('a:nth-of-type(1)');
|
||||
a.href += encodeURIComponent(list.assetKey);
|
||||
a.textContent = list.title;
|
||||
if ( list.supportURL ) {
|
||||
a = span.querySelector('a:nth-of-type(2)');
|
||||
if ( list.supportURL ) {
|
||||
a.setAttribute('href', list.supportURL);
|
||||
} else {
|
||||
a.style.display = 'none';
|
||||
}
|
||||
if ( fragment.childElementCount !== 0 ) {
|
||||
fragment.appendChild(document.createTextNode('\n'));
|
||||
|
@ -1430,24 +1435,31 @@ const netFilteringManager = (function() {
|
|||
if ( response instanceof Object === false ) {
|
||||
response = {};
|
||||
}
|
||||
const fragment = document.createDocumentFragment();
|
||||
let bestMatchFilter = '';
|
||||
for ( const filter in response ) {
|
||||
const spans = nodeFromFilter(filter, response[filter]);
|
||||
if ( spans === undefined ) { continue; }
|
||||
fragment.appendChild(spans);
|
||||
if ( filter.length > bestMatchFilter.length ) {
|
||||
bestMatchFilter = filter;
|
||||
}
|
||||
}
|
||||
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
|
||||
if ( row.children[1].childElementCount === 0 ) {
|
||||
if ( rows[1].children[1].childElementCount === 0 ) {
|
||||
vAPI.i18n.safeTemplateToDOM(
|
||||
'loggerStaticFilteringFinderSentence2',
|
||||
{ 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') ) {
|
||||
messaging.send(
|
||||
|
@ -1499,7 +1511,7 @@ const netFilteringManager = (function() {
|
|||
}
|
||||
// Filter list
|
||||
if ( trcl.contains('canLookup') ) {
|
||||
fillSummaryPaneFilterList(rows[1]);
|
||||
fillSummaryPaneFilterList(rows);
|
||||
} else {
|
||||
rows[1].style.display = 'none';
|
||||
}
|
||||
|
@ -1519,7 +1531,7 @@ const netFilteringManager = (function() {
|
|||
// Partyness
|
||||
text = tr.getAttribute('data-parties') || '';
|
||||
if ( text !== '' ) {
|
||||
rows[5].children[1].textContent = `${trch[4].textContent}\u2002${text}`;
|
||||
rows[5].children[1].textContent = `(${trch[4].textContent})\u2002${text}`;
|
||||
} else {
|
||||
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
|
||||
|
@ -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:
|
||||
// - Give some thoughts to:
|
||||
// - an option to discard immediately filtered out new entries
|
||||
|
@ -2429,16 +2626,9 @@ window.addEventListener('beforeunload', releaseView);
|
|||
|
||||
uDom('#pageSelector').on('change', pageSelectorChanged);
|
||||
uDom('#refresh').on('click', reloadTab);
|
||||
|
||||
uDom('#netInspector .vCompactToggler').on('click', toggleVCompactView);
|
||||
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
|
||||
// Ensure tab selector is in sync with URL hash
|
||||
pageSelectorFromURLHash();
|
||||
|
|
|
@ -25,18 +25,18 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var listEntries = Object.create(null),
|
||||
reBlockStart = /^#block-start-(\d+)\n/gm;
|
||||
const 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;
|
||||
var out = [];
|
||||
var match = reBlockStart.exec(content);
|
||||
const out = [];
|
||||
let match = reBlockStart.exec(content);
|
||||
while ( match !== null ) {
|
||||
var beg = match.index + match[0].length;
|
||||
var blockId = parseInt(match[1], 10);
|
||||
const beg = match.index + match[0].length;
|
||||
const blockId = parseInt(match[1], 10);
|
||||
if ( blockId >= begId && blockId < endId ) {
|
||||
var end = content.indexOf('#block-end-' + match[1], beg);
|
||||
out.push(content.slice(beg, end));
|
||||
|
@ -49,14 +49,14 @@ var extractBlocks = function(content, begId, endId) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var fromNetFilter = function(details) {
|
||||
var lists = [],
|
||||
compiledFilter = details.compiledFilter;
|
||||
const fromNetFilter = function(details) {
|
||||
const lists = [];
|
||||
const compiledFilter = details.compiledFilter;
|
||||
|
||||
for ( let assetKey in listEntries ) {
|
||||
let entry = listEntries[assetKey];
|
||||
for ( const assetKey in listEntries ) {
|
||||
const entry = listEntries[assetKey];
|
||||
if ( entry === undefined ) { continue; }
|
||||
let content = extractBlocks(entry.content, 0, 1000);
|
||||
const content = extractBlocks(entry.content, 0, 1000);
|
||||
let pos = 0;
|
||||
for (;;) {
|
||||
pos = content.indexOf(compiledFilter, pos);
|
||||
|
@ -64,7 +64,7 @@ var fromNetFilter = function(details) {
|
|||
// We need an exact match.
|
||||
// https://github.com/gorhill/uBlock/issues/1392
|
||||
// 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;
|
||||
if (
|
||||
notFound ||
|
||||
|
@ -81,7 +81,7 @@ var fromNetFilter = function(details) {
|
|||
}
|
||||
}
|
||||
|
||||
let response = {};
|
||||
const response = {};
|
||||
response[details.rawFilter] = lists;
|
||||
|
||||
postMessage({
|
||||
|
@ -112,18 +112,18 @@ var fromNetFilter = function(details) {
|
|||
// FilterContainer.fromCompiledContent() is our reference code to create
|
||||
// the various compiled versions.
|
||||
|
||||
let fromCosmeticFilter = function(details) {
|
||||
let match = /^#@?#\^?/.exec(details.rawFilter),
|
||||
prefix = match[0],
|
||||
exception = prefix.charAt(1) === '@',
|
||||
selector = details.rawFilter.slice(prefix.length);
|
||||
const fromCosmeticFilter = function(details) {
|
||||
const match = /^#@?#\^?/.exec(details.rawFilter);
|
||||
const prefix = match[0];
|
||||
const exception = prefix.charAt(1) === '@';
|
||||
const selector = details.rawFilter.slice(prefix.length);
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
let reHostname = new RegExp(
|
||||
const reHostname = new RegExp(
|
||||
'^' +
|
||||
details.hostname.split('.').reduce(
|
||||
function(acc, item) {
|
||||
|
@ -154,16 +154,16 @@ let fromCosmeticFilter = function(details) {
|
|||
);
|
||||
}
|
||||
|
||||
let hostnameMatches = hn => {
|
||||
const hostnameMatches = hn => {
|
||||
return hn === '' ||
|
||||
reHostname.test(hn) ||
|
||||
reEntity !== undefined && reEntity.test(hn);
|
||||
};
|
||||
|
||||
let response = Object.create(null);
|
||||
const response = Object.create(null);
|
||||
|
||||
for ( let assetKey in listEntries ) {
|
||||
let entry = listEntries[assetKey];
|
||||
for ( const assetKey in listEntries ) {
|
||||
const entry = listEntries[assetKey];
|
||||
if ( entry === undefined ) { continue; }
|
||||
let content = extractBlocks(entry.content, 1000, 2000),
|
||||
isProcedural,
|
||||
|
@ -274,7 +274,7 @@ let fromCosmeticFilter = function(details) {
|
|||
/******************************************************************************/
|
||||
|
||||
onmessage = function(e) { // jshint ignore:line
|
||||
var msg = e.data;
|
||||
const msg = e.data;
|
||||
|
||||
switch ( msg.what ) {
|
||||
case 'resetLists':
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
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
|
||||
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
|
||||
// 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 = [];
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ Object.defineProperty(
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var DOMListFactory = function(selector, context) {
|
||||
const DOMListFactory = function(selector, context) {
|
||||
var r = new DOMList();
|
||||
if ( typeof selector === 'string' ) {
|
||||
selector = selector.trim();
|
||||
|
@ -92,7 +92,7 @@ DOMListFactory.nodeFromSelector = function(selector) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var addNodeToList = function(list, node) {
|
||||
const addNodeToList = function(list, node) {
|
||||
if ( 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 ) {
|
||||
var n = nodelist.length;
|
||||
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);
|
||||
return list;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var addSelectorToList = function(list, selector, context) {
|
||||
const addSelectorToList = function(list, selector, context) {
|
||||
var p = context || document;
|
||||
var r = p.querySelectorAll(selector);
|
||||
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) {
|
||||
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;
|
||||
if ( tokenList instanceof DOMTokenList === false ) {
|
||||
return;
|
||||
|
@ -628,7 +619,12 @@ const makeEventHandler = function(selector, callback) {
|
|||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
@ -678,7 +674,7 @@ DOMList.prototype.trigger = function(etype) {
|
|||
|
||||
// Cleanup
|
||||
|
||||
var onBeforeUnload = function() {
|
||||
const onBeforeUnload = function() {
|
||||
var entry;
|
||||
while ( (entry = listenerEntries.pop()) ) {
|
||||
entry.dispose();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<body>
|
||||
|
||||
<div class="permatoolbar">
|
||||
<div>
|
||||
<select id="pageSelector">
|
||||
<option value="0" data-i18n="logAll">
|
||||
<option value="-1" data-i18n="logBehindTheScene">
|
||||
|
@ -22,8 +23,11 @@
|
|||
<span id="refresh" class="button fa-icon disabled needdom" data-i18n-title="loggerReloadTip">refresh</span>
|
||||
<span id="showdom" class="button fa-icon disabled needdom" data-i18n-title="loggerDomInspectorTip">code</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>
|
||||
</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 id="inspectors">
|
||||
<div id="domInspector" class="inspector hCompact">
|
||||
|
@ -42,6 +46,7 @@
|
|||
</div>
|
||||
<div id="netInspector" class="inspector f">
|
||||
<div class="permatoolbar">
|
||||
<div>
|
||||
<span class="button fa-icon vCompactToggler">double-angle-up</span>
|
||||
<span id="clean" class="button fa-icon disabled">times</span>
|
||||
<span id="clear" class="button fa-icon disabled" data-i18n-title="loggerClearTip">eraser</span>
|
||||
|
@ -54,12 +59,16 @@
|
|||
<div id="filterExprPicker">
|
||||
<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="\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="\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(?:0,)?1\t" data-i18n="loggerRowFiltererBuiltin1p"></span><span data-filtex="\t(?:3(?:,\d)?|0,3)\t" data-i18n="loggerRowFiltererBuiltin3p"></span></div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span id="loggerExport" class="button fa-icon">clipboard</span>
|
||||
<span id="settings" class="button fa-icon">cog</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vscrollable">
|
||||
<div id="vwRenderer">
|
||||
<div id="vwScroller">
|
||||
|
@ -163,6 +172,23 @@
|
|||
</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>
|
||||
<textarea class="output" readonly spellcheck="false"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/fa-icons.js"></script>
|
||||
|
|
Loading…
Reference in New Issue