Skip to content

Commit 33c437f

Browse files
committed
Add source code viewer (from logger)
This commits add the ability to open html/css/script resources from the logger, as a formatted and syntax- highligthed document. The goal is to make it easier for filter list authors to investigate filter-related issues.
1 parent db11848 commit 33c437f

File tree

17 files changed

+2588
-25
lines changed

17 files changed

+2588
-25
lines changed

src/1p-filters.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<button id="exportUserFiltersToFile" class="iconified" type="button"><span class="fa-icon">upload-alt</span><span data-i18n="1pExport">_</span><span class="hover"></span></button>
3434
</p>
3535
</div>
36-
<div id="userFilters" class="codeMirrorContainer codeMirrorBreakAll" spellcheck="false"></div>
36+
<div id="userFilters" class="codeMirrorContainer codeMirrorBreakAll codeMirrorFilters" spellcheck="false"></div>
3737
<div class="hidden">
3838
<input id="importFilePicker" type="file" accept="text/plain">
3939
</div>

src/about.html

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<div class="li"><span><a href="https://github.com/hsluv/hsluv" target="_blank">HSLuv - Human-friendly HSL</a> by <a href="https://github.com/boronine">Alexei Boronine</a></span></div>
3939
<div class="li"><span><a href="https://searchfox.org/mozilla-central/rev/d317e93d9a59c9e4c06ada85fbff9f6a1ceaaad1/browser/extensions/webcompat/shims/google-ima.js" target="_blank">google-ima.js</a> by <a href="https://www.mozilla.org/">Mozilla</a></span></div>
4040
<div class="li"><span><a href="https://github.com/csstree/csstree" target="_blank">CSSTree</a> by <a href="https://github.com/lahmatiy">Roman Dvornov</a></span></div>
41+
<div class="li"><span><a href="https://github.com/beautify-web/js-beautify" target="_blank">js-beautify</a> by <a href="https://github.com/einars">Einar Lielmanis</a>, <a href="https://github.com/bitwiseman">Liam Newman</a>, et al.</span></div>
4142
</div>
4243
<div class="li"><span data-i18n="aboutCDNs"></span></div>
4344
<div class="liul">

src/asset-viewer.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
88
<link rel="stylesheet" href="lib/codemirror/addon/fold/foldgutter.css">
99
<link rel="stylesheet" href="lib/codemirror/addon/search/matchesonscrollbar.css">
10-
<link rel="stylesheet" type="text/css" href="css/themes/default.css">
10+
<link rel="stylesheet" href="css/themes/default.css">
1111
<link rel="stylesheet" href="css/common.css">
1212
<link rel="stylesheet" href="css/fa-icons.css">
1313
<link rel="stylesheet" href="css/codemirror.css">
@@ -17,13 +17,13 @@
1717
<body class="loading">
1818

1919
<section id="subscribe" class="hide notice">
20-
<span class="logo"><img data-i18n-title="extName" src="img/ublock.svg"></span>
20+
<span class="logo"><img data-i18n-title="extName" src="img/ublock.svg" alt="logo"></span>
2121
<span id="subscribePrompt"><span></span><a></a></span>
2222
<span class="fa-icon">spinner</span>
2323
<button id="subscribeButton" type="button" data-i18n="subscribeButton">_<span class="hover"></span></button>
2424
</section>
2525

26-
<div id="content" class="codeMirrorContainer codeMirrorBreakAll"></div>
26+
<div id="content" class="codeMirrorContainer codeMirrorBreakAll codeMirrorFilters"></div>
2727

2828
<script src="lib/codemirror/lib/codemirror.js"></script>
2929
<script src="lib/codemirror/addon/display/panel.js"></script>

src/code-viewer.html

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Code viewer</title>
7+
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
8+
<link rel="stylesheet" href="lib/codemirror/theme/night.css">
9+
<link rel="stylesheet" href="lib/codemirror/addon/search/matchesonscrollbar.css">
10+
<link rel="stylesheet" href="css/themes/default.css">
11+
<link rel="stylesheet" href="css/common.css">
12+
<link rel="stylesheet" href="css/fa-icons.css">
13+
<link rel="stylesheet" href="css/codemirror.css">
14+
<link rel="stylesheet" href="css/code-viewer.css">
15+
</head>
16+
<body class="loading">
17+
18+
<div id="content" class="codeMirrorContainer codeMirrorBreakAll"></div>
19+
20+
<script src="lib/codemirror/lib/codemirror.js"></script>
21+
<script src="lib/codemirror/addon/display/panel.js"></script>
22+
<script src="lib/codemirror/addon/scroll/annotatescrollbar.js"></script>
23+
<script src="lib/codemirror/addon/search/searchcursor.js"></script>
24+
<script src="lib/codemirror/addon/selection/active-line.js"></script>
25+
<script src="lib/codemirror/mode/javascript/javascript.js"></script>
26+
<script src="lib/codemirror/mode/css/css.js"></script>
27+
<script src="lib/codemirror/mode/xml/xml.js"></script>
28+
<script src="lib/codemirror/mode/htmlmixed/htmlmixed.js"></script>
29+
30+
<script src="js/codemirror/search.js"></script>
31+
<script src="js/codemirror/search-thread.js"></script>
32+
<script src="lib/js-beautify/beautify.min.js"></script>
33+
<script src="js/fa-icons.js"></script>
34+
<script src="js/vapi.js"></script>
35+
<script src="js/vapi-common.js"></script>
36+
<script src="js/vapi-client.js"></script>
37+
<script src="js/theme.js" type="module"></script>
38+
<script src="js/i18n.js" type="module"></script>
39+
<script src="js/dashboard-common.js" type="module"></script>
40+
<script src="js/code-viewer.js" type="module"></script>
41+
</body>
42+
</html>

src/css/code-viewer.css

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
body {
2+
border: 0;
3+
display: flex;
4+
flex-direction: column;
5+
height: 100vh;
6+
margin: 0;
7+
overflow: hidden;
8+
padding: 0;
9+
width: 100vw;
10+
}
11+
#content {
12+
flex-grow: 1;
13+
}

src/css/codemirror.css

+19-17
Original file line numberDiff line numberDiff line change
@@ -68,65 +68,67 @@
6868
word-break: break-all;
6969
}
7070

71-
.cm-s-default .cm-comment {
71+
.codeMirrorFilters .cm-s-default .cm-comment {
7272
color: var(--sf-comment-ink);
7373
}
74-
.cm-s-default .cm-def {
74+
.codeMirrorFilters .cm-s-default .cm-def {
7575
color: var(--sf-def-ink);
7676
}
77-
.cm-s-default .cm-directive {
77+
.codeMirrorFilters .cm-s-default .cm-directive {
7878
color: var(--sf-directive-ink);
7979
font-weight: bold;
8080
}
81-
.cm-s-default .cm-error {
81+
.codeMirrorFilters .cm-s-default .cm-error {
8282
color: inherit;
8383
}
84-
.cm-s-default .cm-error,
84+
.codeMirrorFilters .cm-s-default .cm-error,
8585
.CodeMirror-linebackground.error {
8686
background-color: var(--sf-error-surface);
8787
text-decoration: underline var(--sf-error-ink);
8888
text-underline-position: under;
8989
}
90-
.cm-s-default .cm-link {
90+
.codeMirrorFilters .cm-s-default .cm-link {
9191
text-decoration: none;
9292
}
93-
.cm-s-default .cm-link:hover {
93+
.codeMirrorFilters .cm-s-default .cm-link:hover {
9494
color: var(--link-ink);
9595
}
96-
.cm-s-default .cm-keyword {
96+
.codeMirrorFilters .cm-s-default .cm-keyword {
9797
color: var(--sf-keyword-ink);
9898
}
99-
.cm-s-default .cm-negative {
99+
.codeMirrorFilters .cm-s-default .cm-negative {
100100
color: var(--cm-negative);
101101
}
102-
.cm-s-default .cm-positive {
102+
.codeMirrorFilters .cm-s-default .cm-positive {
103103
color: var(--cm-positive);
104104
}
105-
.cm-s-default .cm-notice {
105+
.codeMirrorFilters .cm-s-default .cm-notice {
106106
text-underline-position: under;
107107
text-decoration-color: var(--sf-notice-ink);
108108
text-decoration-style: solid;
109109
text-decoration-line: underline;
110110
}
111-
.cm-s-default .cm-unicode {
111+
.codeMirrorFilters .cm-s-default .cm-unicode {
112112
text-underline-position: under;
113113
text-decoration-color: var(--sf-unicode-ink);
114114
text-decoration-style: dashed;
115115
text-decoration-line: underline;
116116
}
117-
.cm-s-default .cm-tag {
117+
.codeMirrorFilters .cm-s-default .cm-tag {
118118
color: var(--sf-tag-ink);
119119
}
120-
.cm-s-default .cm-value { color: var(--sf-value-ink); }
121-
.cm-s-default .cm-variable {
120+
.codeMirrorFilters .cm-s-default .cm-value {
121+
color: var(--sf-value-ink);
122+
}
123+
.codeMirrorFilters .cm-s-default .cm-variable {
122124
color: var(--sf-variable-ink);
123125
}
124-
.cm-s-default .cm-warning {
126+
.codeMirrorFilters .cm-s-default .cm-warning {
125127
background-color: var(--sf-warning-surface);
126128
text-decoration: underline var(--sf-warning-ink);
127129
text-underline-position: under;
128130
}
129-
.cm-s-default .cm-readonly {
131+
.codeMirrorFilters .cm-s-default .cm-readonly {
130132
color: var(--sf-readonly-ink);
131133
}
132134

src/js/code-viewer.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*******************************************************************************
2+
3+
uBlock Origin - a browser extension to block requests.
4+
Copyright (C) 2023-present Raymond Hill
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see {http://www.gnu.org/licenses/}.
18+
19+
Home: https://github.com/gorhill/uBlock
20+
*/
21+
22+
/* globals CodeMirror, uBlockDashboard, beautifier */
23+
24+
'use strict';
25+
26+
/******************************************************************************/
27+
28+
import { dom, qs$ } from './dom.js';
29+
30+
/******************************************************************************/
31+
32+
(async ( ) => {
33+
const params = new URLSearchParams(document.location.search);
34+
const url = params.get('url');
35+
const a = qs$('.cm-search-widget .sourceURL');
36+
dom.attr(a, 'href', url);
37+
dom.attr(a, 'title', url);
38+
const response = await fetch(url);
39+
const text = await response.text();
40+
const formatOptions = { indent_size: 2 };
41+
let value = '', mode = '';
42+
switch ( params.get('type') ) {
43+
case 'css':
44+
mode = 'text/css';
45+
value = beautifier.css(text, formatOptions);
46+
break;
47+
case 'html':
48+
mode = 'text/html';
49+
value = beautifier.html(text, formatOptions);
50+
break;
51+
case 'js':
52+
mode = 'text/javascript';
53+
value = beautifier.js(text, formatOptions);
54+
break;
55+
default:
56+
break;
57+
}
58+
const cmEditor = new CodeMirror(qs$('#content'), {
59+
autofocus: true,
60+
gutters: [ 'CodeMirror-linenumbers' ],
61+
lineNumbers: true,
62+
lineWrapping: true,
63+
mode,
64+
readOnly: true,
65+
styleActiveLine: {
66+
nonEmpty: true,
67+
},
68+
value,
69+
});
70+
uBlockDashboard.patchCodeMirrorEditor(cmEditor);
71+
if ( dom.cl.has(dom.html, 'dark') ) {
72+
dom.cl.add('#content .cm-s-default', 'cm-s-night');
73+
dom.cl.remove('#content .cm-s-default', 'cm-s-default');
74+
}
75+
})();

src/js/logger-ui.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const regexFromURLFilteringResult = function(result) {
253253

254254
// Emphasize hostname in URL, as this is what matters in uMatrix's rules.
255255

256-
const nodeFromURL = function(parent, url, re) {
256+
const nodeFromURL = function(parent, url, re, type) {
257257
const fragment = document.createDocumentFragment();
258258
if ( re === undefined ) {
259259
fragment.textContent = url;
@@ -282,7 +282,22 @@ const nodeFromURL = function(parent, url, re) {
282282
}
283283
if ( /^https?:\/\//.test(url) ) {
284284
const a = document.createElement('a');
285-
dom.attr(a, 'href', url);
285+
let href = url;
286+
switch ( type ) {
287+
case 'css':
288+
href = `code-viewer.html?url=${encodeURIComponent(url)}&type=css`;
289+
break;
290+
case 'doc':
291+
case 'frame':
292+
href = `code-viewer.html?url=${encodeURIComponent(url)}&type=html`;
293+
break
294+
case 'script':
295+
href = `code-viewer.html?url=${encodeURIComponent(url)}&type=js`;
296+
break;
297+
default:
298+
break;
299+
}
300+
dom.attr(a, 'href', href);
286301
dom.attr(a, 'target', '_blank');
287302
fragment.appendChild(a);
288303
}
@@ -862,7 +877,7 @@ const viewPort = (( ) => {
862877
} else if ( filteringType === 'dynamicUrl' ) {
863878
re = regexFromURLFilteringResult(filter.rule.join(' '));
864879
}
865-
nodeFromURL(div.children[COLUMN_URL], cells[COLUMN_URL], re);
880+
nodeFromURL(div.children[COLUMN_URL], cells[COLUMN_URL], re, cells[COLUMN_TYPE]);
866881

867882
// Alias URL (CNAME, etc.)
868883
if ( cells.length > 8 ) {

0 commit comments

Comments
 (0)