1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-14 23:12:28 +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": ""
},
"settingsNoLargeMediaPrompt":{
"message":"Block media elements larger than {{input}} kB",
"message":"Block media elements larger than {{input}} KB",
"description": ""
},
"settingsNoRemoteFontsPrompt":{

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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;
a = span.querySelector('a:nth-of-type(2)');
if ( list.supportURL ) {
a = span.querySelector('a:nth-of-type(2)');
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();

View File

@ -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':

View File

@ -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();

View File

@ -14,15 +14,19 @@
<body>
<div class="permatoolbar">
<select id="pageSelector">
<option value="0" data-i18n="logAll">
<option value="-1" data-i18n="logBehindTheScene">
<option value="_" data-i18n="loggerCurrentTab">
</select>
<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>
<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>
<select id="pageSelector">
<option value="0" data-i18n="logAll">
<option value="-1" data-i18n="logBehindTheScene">
<option value="_" data-i18n="loggerCurrentTab">
</select>
<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">
@ -42,23 +46,28 @@
</div>
<div id="netInspector" class="inspector f">
<div class="permatoolbar">
<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>
<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="filterExprGroup">
<span id="filterButton" class="button fa-icon" data-i18n-title="loggerRowFiltererButtonTip">filter</span>
<span id="filterInput">
<input type="text" placeholder="logFilterPrompt">
<span id="filterExprButton" class="button fa-icon expanded" data-i18n-title="loggerRowFiltererBuiltinTip">angle-up</span>
<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>
<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>
<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="filterExprGroup">
<span id="filterButton" class="button fa-icon" data-i18n-title="loggerRowFiltererButtonTip">filter</span>
<span id="filterInput">
<input type="text" placeholder="logFilterPrompt">
<span id="filterExprButton" class="button fa-icon expanded" data-i18n-title="loggerRowFiltererBuiltinTip">angle-up</span>
<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="\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 id="settings" class="button fa-icon">cog</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">
@ -162,7 +171,24 @@
</ul>
</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>