snapshot of c000b74a5b09c433f96a69fa102c5c8f6583dff0 Annotations about the code that implements koment.

integrations/editors/vscode/panel.js

1 'use strict';
2
3 const statusTone = {
4 ok: 'ok',
5 ambiguous: 'failing',
6 drifted: 'failing',
7 orphaned: 'failing'
8 };
9
10 function escape(text) {
11 return String(text ?? '').replace(
12 /[&<>"']/g,
13 (character) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[character]
14 );
15 }
16
17 function paragraphs(body) {
18 return String(body ?? '')
19 .split(/\n{2,}/)
20 .map((block) => block.trim())
21 .filter(Boolean)
22 .map((block) => `<p>${escape(block).replace(/\n/g, '<br>')}</p>`)
23 .join('');
24 }
25
26 function entry(item, index) {
27 const tone = statusTone[item.status] ?? 'failing';
28 const warning = item.warning ? `<p class="warning">${escape(item.warning)}</p>` : '';
29 return `<li>
30 <button type="button" data-reveal="${index}">
31 <span class="title">${escape(item.title)}</span>
32 <span class="meta"><span class="kind">${escape(item.kind)}</span><span class="status ${tone}">${escape(item.status)}</span><span class="line">L${Number(item.line) || 0}</span></span>
33 <span class="body">${paragraphs(item.body)}${warning}</span>
34 </button>
35 </li>`;
36 }
37
38 function panelHTML({ items, file, nonce, styleNonce }) {
39 const list = items.length
40 ? `<ul>${items.map(entry).join('')}</ul>`
41 : `<p class="empty">No annotations in this file.</p>`;
42 return `<!DOCTYPE html>
43 <html lang="en">
44 <head>
45 <meta charset="utf-8">
46 <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${styleNonce}'; script-src 'nonce-${nonce}';">
47 <style nonce="${styleNonce}">
48 :root { color-scheme: light dark; }
49 body {
50 margin: 0; padding: 0.4rem 0.2rem;
51 font-family: var(--vscode-font-family); font-size: var(--vscode-font-size);
52 color: var(--vscode-foreground); background: transparent;
53 }
54 ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; }
55 button {
56 display: block; width: 100%; text-align: left; cursor: pointer;
57 background: none; border: none; border-left: 2px solid transparent;
58 padding: 0.45rem 0.6rem; color: inherit; font: inherit;
59 }
60 button:hover { background: var(--vscode-list-hoverBackground); }
61 button:focus-visible { outline: 1px solid var(--vscode-focusBorder); outline-offset: -1px; }
62 .title { display: block; font-weight: 600; margin-bottom: 0.15rem; }
63 .meta { display: flex; gap: 0.5rem; align-items: baseline; margin-bottom: 0.3rem; }
64 .kind { color: var(--vscode-descriptionForeground); }
65 .status { font-size: 0.85em; text-transform: uppercase; letter-spacing: 0.04em; }
66 .status.ok { color: var(--vscode-descriptionForeground); }
67 .status.moved { color: var(--vscode-editorWarning-foreground); }
68 .status.failing { color: var(--vscode-editorError-foreground); }
69 .line { margin-left: auto; color: var(--vscode-descriptionForeground); font-variant-numeric: tabular-nums; }
70 .body p { margin: 0 0 0.4rem; line-height: 1.45; white-space: normal; }
71 .body p:last-child { margin-bottom: 0; }
72 .warning { color: var(--vscode-editorError-foreground); }
73 .empty { color: var(--vscode-descriptionForeground); padding: 0.6rem; }
74 .file { color: var(--vscode-descriptionForeground); padding: 0 0.6rem 0.4rem; }
75 </style>
76 </head>
77 <body>
78 ${file ? `<p class="file">${escape(file)}</p>` : ''}
79 ${list}
80 <script nonce="${nonce}">
81 const vscode = acquireVsCodeApi();
82 document.addEventListener('click', (event) => {
83 const target = event.target.closest('[data-reveal]');
84 if (target) {
85 vscode.postMessage({ reveal: Number(target.dataset.reveal) });
86 }
87 });
88 </script>
89 </body>
90 </html>`;
91 }
92
93 module.exports = { escape, panelHTML, paragraphs };

Find an annotation

Search file paths, rationale, kinds, and authors.

moveEnter openEsc close