Merge pull request 'feat(ui): render markdown in peek pane' (#18) from feat/peek-markdown into main
Reviewed-on: #18
This commit was merged in pull request #18.
This commit is contained in:
+12
-2
@@ -768,7 +768,7 @@
|
|||||||
<span class="peek-brow-ts">${fmtDateLong(e.created_at)}</span>
|
<span class="peek-brow-ts">${fmtDateLong(e.created_at)}</span>
|
||||||
</div>
|
</div>
|
||||||
${e.title ? `<div class="peek-title" data-id="${e.id}">${escHtml(e.title)}</div>` : ''}
|
${e.title ? `<div class="peek-title" data-id="${e.id}">${escHtml(e.title)}</div>` : ''}
|
||||||
<div class="peek-body" data-id="${e.id}">${escHtml(e.body)}</div>
|
<div class="peek-body md" data-id="${e.id}">${renderMd(e.body)}</div>
|
||||||
${tags ? `<div class="peek-sec"><div class="peek-sec-lbl">tags</div><div class="peek-sec-inner tag-pills">${tags}</div></div>` : ''}
|
${tags ? `<div class="peek-sec"><div class="peek-sec-lbl">tags</div><div class="peek-sec-inner tag-pills">${tags}</div></div>` : ''}
|
||||||
<div class="peek-sec">
|
<div class="peek-sec">
|
||||||
<div class="peek-sec-lbl">context</div>
|
<div class="peek-sec-lbl">context</div>
|
||||||
@@ -825,9 +825,13 @@
|
|||||||
|
|
||||||
if (!hasDecision && e.body) {
|
if (!hasDecision && e.body) {
|
||||||
const lang = data.lang || '';
|
const lang = data.lang || '';
|
||||||
|
const isCode = lang || e.card_type === 'snippet';
|
||||||
|
const bodyHtml = isCode
|
||||||
|
? `<div class="peek-code"><pre><code>${escHtml(e.body)}</code></pre></div>`
|
||||||
|
: `<div class="peek-body md">${renderMd(e.body)}</div>`;
|
||||||
sections += `<div class="peek-sec">
|
sections += `<div class="peek-sec">
|
||||||
<div class="peek-sec-lbl">content${lang ? `<span class="peek-sec-lang">${lang}</span>` : ''}${hasFill ? `<button class="peek-sec-run" onclick="nibApp.enterMode('fill')">⤓ fill</button>` : ''}</div>
|
<div class="peek-sec-lbl">content${lang ? `<span class="peek-sec-lang">${lang}</span>` : ''}${hasFill ? `<button class="peek-sec-run" onclick="nibApp.enterMode('fill')">⤓ fill</button>` : ''}</div>
|
||||||
<div class="peek-sec-inner"><div class="peek-code"><pre><code>${escHtml(e.body)}</code></pre></div></div>
|
<div class="peek-sec-inner">${bodyHtml}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1629,6 +1633,12 @@
|
|||||||
return escHtml(s).replace(/'/g, ''');
|
return escHtml(s).replace(/'/g, ''');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderMd(s) {
|
||||||
|
if (!s) return '';
|
||||||
|
if (typeof marked === 'undefined') return escHtml(s);
|
||||||
|
return marked.parse(s, { breaks: true });
|
||||||
|
}
|
||||||
|
|
||||||
function isSafeUrl(url) {
|
function isSafeUrl(url) {
|
||||||
return /^https?:\/\//i.test(url);
|
return /^https?:\/\//i.test(url);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/marked@15/marked.min.js"></script>
|
||||||
<script src="/app.js"></script>
|
<script src="/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -877,6 +877,85 @@ kbd { background: var(--raised); border: 1px solid var(--border); border-radius:
|
|||||||
|
|
||||||
.peek-body:hover { background: var(--raised); }
|
.peek-body:hover { background: var(--raised); }
|
||||||
|
|
||||||
|
.peek-body.md {
|
||||||
|
font-family: var(--sans);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.65;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md h1, .peek-body.md h2, .peek-body.md h3,
|
||||||
|
.peek-body.md h4, .peek-body.md h5, .peek-body.md h6 {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text);
|
||||||
|
margin: 14px 0 6px;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md h1 { font-size: 17px; }
|
||||||
|
.peek-body.md h2 { font-size: 15px; }
|
||||||
|
.peek-body.md h3 { font-size: 14px; }
|
||||||
|
|
||||||
|
.peek-body.md p { margin: 0 0 10px; }
|
||||||
|
.peek-body.md p:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.peek-body.md ul, .peek-body.md ol {
|
||||||
|
padding-left: 20px;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md li { margin-bottom: 3px; }
|
||||||
|
|
||||||
|
.peek-body.md blockquote {
|
||||||
|
border-left: 2px solid var(--accent);
|
||||||
|
padding-left: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md code {
|
||||||
|
font-family: var(--mono);
|
||||||
|
font-size: 11px;
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--r1);
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md pre {
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--r2);
|
||||||
|
padding: 10px 12px;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md pre code {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md a {
|
||||||
|
color: var(--event);
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid rgba(104,152,200,.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.peek-body.md a:hover { border-bottom-color: var(--event); }
|
||||||
|
|
||||||
|
.peek-body.md strong { font-weight: 600; }
|
||||||
|
.peek-body.md em { font-style: italic; color: var(--muted); }
|
||||||
|
|
||||||
|
.peek-body.md hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
margin: 14px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.peek-meta {
|
.peek-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user