Skip to content

Commit b28865e

Browse files
authored
Merge pull request #51 from adobe/syntax-highlight
feat: syntax highlight
2 parents 74b8b49 + b70a421 commit b28865e

File tree

3 files changed

+133
-5
lines changed

3 files changed

+133
-5
lines changed

tools/log-viewer/scripts.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
/* eslint-disable class-methods-use-this */
2+
import { loadPrism, highlight } from '../../utils/prism/prism.js';
3+
24
// utility functions
35
function getFormData(form) {
46
const data = {};
@@ -88,15 +90,17 @@ function calculatePastDate(days, hours, mins, now = new Date()) {
8890

8991
// loading button management
9092
function showLoadingButton(button) {
91-
const { width } = button.getBoundingClientRect();
93+
button.disabled = true;
94+
const { width, height } = button.getBoundingClientRect();
9295
button.style.minWidth = `${width}px`;
96+
button.style.minHeight = `${height}px`;
9397
button.dataset.label = button.textContent;
9498
button.innerHTML = '<i class="symbol symbol-loading"></i>';
9599
}
96100

97101
function resetLoadingButton(button) {
98-
button.removeAttribute('style');
99102
button.textContent = button.dataset.label;
103+
button.removeAttribute('style');
100104
button.disabled = false;
101105
}
102106

@@ -146,18 +150,20 @@ function writeLoginMessage(owner, repo) {
146150
function registerAdminDetailsListener(buttons) {
147151
buttons.forEach((button) => {
148152
button.addEventListener('click', async () => {
153+
showLoadingButton(button);
149154
const url = new URL(button.dataset.url);
150155
const { createModal } = await import('../../blocks/modal/modal.js');
151156
if (url) {
152157
const res = await fetch(url);
153158
const jsonContent = await res.json();
154159
const modalContent = document.createElement('div');
155-
modalContent.innerHTML = `<pre>
156-
${JSON.stringify(jsonContent, null, 3)}
157-
</pre>`;
160+
modalContent.innerHTML = `<pre><code class="language-js">${JSON.stringify(jsonContent, null, 2)}
161+
</code></pre>`;
158162
const { showModal } = await createModal(modalContent.childNodes);
159163
showModal();
164+
highlight(document.querySelector('.modal'));
160165
}
166+
resetLoadingButton(button);
161167
});
162168
});
163169
}
@@ -473,6 +479,8 @@ function registerListeners(doc) {
473479
} else updateTableError('Site URL', 'Enter a valid hlx/aem page or live URL to see logs.');
474480
});
475481

482+
TIMEFRAME_FORM.addEventListener('submit', loadPrism, { once: true });
483+
476484
TIMEFRAME_FORM.addEventListener('reset', (e) => {
477485
e.preventDefault();
478486
SITE_FIELD.value = '';

utils/prism/prism.css

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* PrismJS 1.29.0 (Default), slightly altered
2+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+json */
3+
4+
code[class*='language-'],
5+
pre[class*='language-'] {
6+
color: var(--color-text);
7+
text-align: left;
8+
white-space: pre;
9+
word-break: normal;
10+
word-spacing: normal;
11+
word-wrap: normal;
12+
-webkit-hyphens: none;
13+
-moz-hyphens: none;
14+
-ms-hyphens: none;
15+
hyphens: none;
16+
-moz-tab-size: 2;
17+
-o-tab-size: 2;
18+
tab-size: 2;
19+
}
20+
21+
pre[class*='language-'] {
22+
overflow: auto;
23+
}
24+
25+
.token.cdata,
26+
.token.comment,
27+
.token.doctype,
28+
.token.prolog {
29+
color: #708090;
30+
}
31+
32+
.token.punctuation {
33+
color: #999;
34+
}
35+
36+
.token.namespace {
37+
opacity: 0.8;
38+
}
39+
40+
.token.property {
41+
color: #4b0082;
42+
}
43+
44+
.token.boolean,
45+
.token.constant,
46+
.token.deleted,
47+
.token.number,
48+
.token.symbol,
49+
.token.tag {
50+
color: #905;
51+
}
52+
53+
.token.attr-name,
54+
.token.builtin,
55+
.token.char,
56+
.token.inserted,
57+
.token.selector,
58+
.token.string {
59+
color: #690;
60+
}
61+
62+
.language-css .token.string,
63+
.style .token.string,
64+
.token.entity,
65+
.token.operator,
66+
.token.url {
67+
color: #9a6e3a;
68+
}
69+
70+
.token.atrule,
71+
.token.attr-value,
72+
.token.keyword {
73+
color: #07a;
74+
}
75+
76+
.token.class-name,
77+
.token.function {
78+
color: #dd4a68;
79+
}
80+
81+
.token.important,
82+
.token.regex,
83+
.token.variable {
84+
color: #e90;
85+
}
86+
87+
.token.bold,
88+
.token.important {
89+
font-weight: 700;
90+
}
91+
92+
.token.italic {
93+
font-style: italic;
94+
}
95+
96+
.token.entity {
97+
cursor: help;
98+
}

utils/prism/prism.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* eslint-disable no-undef */
2+
import { loadScript, loadCSS } from '../../scripts/aem.js';
3+
4+
/**
5+
* Highlights <pre><code> element with Prism.js.
6+
* @param {HTMLElement} el - Element to search for <pre><code>.
7+
*/
8+
export function highlight(el) {
9+
const code = el.nodeName === 'CODE' ? el : el.querySelector('pre > code[class^="language"]');
10+
if (code) Prism.highlightElement(code);
11+
}
12+
13+
/**
14+
* Loads Prism.js library and associated CSS for syntax highlighting.
15+
* @param {Event} e - Event object containing target element to highlight, if available.
16+
*/
17+
export function loadPrism(e) {
18+
loadScript('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js').then(() => {
19+
loadCSS('../../utils/prism/prism.css');
20+
if (e.target) highlight(e.target);
21+
});
22+
}

0 commit comments

Comments
 (0)