|
|
|
|
@ -10,6 +10,9 @@
@@ -10,6 +10,9 @@
|
|
|
|
|
import { getHighlightsForEvent, findHighlightMatches, type Highlight } from '../../services/nostr/highlight-service.js'; |
|
|
|
|
import { mountComponent } from './mount-component-action.js'; |
|
|
|
|
import type { NostrEvent } from '../../types/nostr.js'; |
|
|
|
|
import hljs from 'highlight.js'; |
|
|
|
|
// Use VS Code theme for IDE-like appearance |
|
|
|
|
import 'highlight.js/styles/vs2015.css'; |
|
|
|
|
|
|
|
|
|
import EmbeddedEvent from './EmbeddedEvent.svelte'; |
|
|
|
|
let mountingEmbeddedEvents = $state(false); // Guard for mounting |
|
|
|
|
@ -437,6 +440,7 @@
@@ -437,6 +440,7 @@
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Configure marked once - ensure images are rendered and HTML is preserved |
|
|
|
|
// Note: Code highlighting is done post-render in the effect below, not via marked options |
|
|
|
|
marked.setOptions({ |
|
|
|
|
breaks: true, // Convert line breaks to <br> |
|
|
|
|
gfm: true, // GitHub Flavored Markdown |
|
|
|
|
@ -826,6 +830,66 @@
@@ -826,6 +830,66 @@
|
|
|
|
|
// Use requestAnimationFrame + setTimeout to ensure DOM is ready |
|
|
|
|
const frameId = requestAnimationFrame(() => { |
|
|
|
|
const timeoutId = setTimeout(() => { |
|
|
|
|
if (!containerRef) return; |
|
|
|
|
|
|
|
|
|
// Highlight code blocks (both Markdown and AsciiDoc) |
|
|
|
|
// Markdown: <pre><code> |
|
|
|
|
const codeBlocks = containerRef.querySelectorAll('pre code'); |
|
|
|
|
codeBlocks.forEach((block) => { |
|
|
|
|
if (!block.classList.contains('hljs')) { |
|
|
|
|
const code = block.textContent || ''; |
|
|
|
|
const className = block.className || ''; |
|
|
|
|
const langMatch = className.match(/language-(\w+)/); |
|
|
|
|
const lang = langMatch ? langMatch[1] : ''; |
|
|
|
|
|
|
|
|
|
if (lang && hljs.getLanguage(lang)) { |
|
|
|
|
try { |
|
|
|
|
block.innerHTML = hljs.highlight(code, { language: lang }).value; |
|
|
|
|
block.className = `hljs ${className}`; |
|
|
|
|
} catch (err) { |
|
|
|
|
console.warn('Highlight.js error:', err); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
block.innerHTML = hljs.highlightAuto(code).value; |
|
|
|
|
block.className = `hljs ${className}`; |
|
|
|
|
} catch (err) { |
|
|
|
|
console.warn('Highlight.js auto-detect error:', err); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// AsciiDoc: <div class="listingblock"><pre><code> or <pre class="highlight"><code> |
|
|
|
|
if (!containerRef) return; |
|
|
|
|
const asciidocBlocks = containerRef.querySelectorAll('.listingblock pre code, pre.highlight code'); |
|
|
|
|
asciidocBlocks.forEach((block) => { |
|
|
|
|
if (!block.classList.contains('hljs')) { |
|
|
|
|
const code = block.textContent || ''; |
|
|
|
|
// AsciiDoc might have language in data-lang or class |
|
|
|
|
const preElement = block.closest('pre'); |
|
|
|
|
const lang = preElement?.getAttribute('data-lang') || |
|
|
|
|
preElement?.className.match(/(?:^|\s)language-(\w+)/)?.[1] || |
|
|
|
|
block.className.match(/(?:^|\s)language-(\w+)/)?.[1] || ''; |
|
|
|
|
|
|
|
|
|
if (lang && hljs.getLanguage(lang)) { |
|
|
|
|
try { |
|
|
|
|
block.innerHTML = hljs.highlight(code, { language: lang }).value; |
|
|
|
|
block.className = `hljs ${block.className}`; |
|
|
|
|
} catch (err) { |
|
|
|
|
console.warn('Highlight.js error:', err); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
block.innerHTML = hljs.highlightAuto(code).value; |
|
|
|
|
block.className = `hljs ${block.className}`; |
|
|
|
|
} catch (err) { |
|
|
|
|
console.warn('Highlight.js auto-detect error:', err); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
mountProfileBadges(); |
|
|
|
|
mountEmbeddedEvents(); |
|
|
|
|
}, 150); |
|
|
|
|
@ -998,6 +1062,64 @@
@@ -998,6 +1062,64 @@
|
|
|
|
|
padding: 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* IDE-style code block styling - always dark/black background like VS Code/JetBrains */ |
|
|
|
|
:global(.markdown-content pre) { |
|
|
|
|
background: #1e1e1e !important; /* VS Code dark background */ |
|
|
|
|
border: 1px solid #3e3e3e; |
|
|
|
|
border-radius: 4px; |
|
|
|
|
padding: 1rem; |
|
|
|
|
margin: 1rem 0; |
|
|
|
|
overflow-x: auto; |
|
|
|
|
position: relative; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:global(.markdown-content pre code.hljs) { |
|
|
|
|
display: block; |
|
|
|
|
overflow-x: auto; |
|
|
|
|
padding: 0; |
|
|
|
|
background: transparent !important; |
|
|
|
|
color: #d4d4d4; /* VS Code text color */ |
|
|
|
|
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', 'Droid Sans Mono', 'Source Code Pro', monospace; |
|
|
|
|
font-size: 0.9em; |
|
|
|
|
line-height: 1.5; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Inline code - keep light styling but make it subtle */ |
|
|
|
|
:global(.markdown-content code.hljs:not(pre code)) { |
|
|
|
|
padding: 0.2em 0.4em; |
|
|
|
|
border-radius: 0.25rem; |
|
|
|
|
background: var(--fog-border, #e5e7eb); |
|
|
|
|
color: inherit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:global(.dark .markdown-content code.hljs:not(pre code)) { |
|
|
|
|
background: var(--fog-dark-border, #374151); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Ensure pre blocks always have dark background regardless of theme */ |
|
|
|
|
:global(.markdown-content pre) { |
|
|
|
|
background: #1e1e1e !important; |
|
|
|
|
border-color: #3e3e3e !important; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* AsciiDoc code blocks - same styling */ |
|
|
|
|
:global(.markdown-content .listingblock pre) { |
|
|
|
|
background: #1e1e1e !important; |
|
|
|
|
border: 1px solid #3e3e3e; |
|
|
|
|
border-radius: 4px; |
|
|
|
|
padding: 1rem; |
|
|
|
|
margin: 1rem 0; |
|
|
|
|
overflow-x: auto; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:global(.markdown-content .listingblock pre code.hljs) { |
|
|
|
|
background: transparent !important; |
|
|
|
|
color: #d4d4d4; |
|
|
|
|
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', 'Droid Sans Mono', 'Source Code Pro', monospace; |
|
|
|
|
font-size: 0.9em; |
|
|
|
|
line-height: 1.5; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:global(.markdown-content blockquote) { |
|
|
|
|
border-left: 4px solid var(--fog-border, #e5e7eb); |
|
|
|
|
padding-left: 1rem; |
|
|
|
|
@ -1012,14 +1134,14 @@
@@ -1012,14 +1134,14 @@
|
|
|
|
|
|
|
|
|
|
/* Greentext styling - 4chan style */ |
|
|
|
|
:global(.markdown-content .greentext) { |
|
|
|
|
color: #789922; |
|
|
|
|
color: #4a7c3a; /* Deeper, darker green for better readability in light mode */ |
|
|
|
|
display: block; |
|
|
|
|
margin: 0.25rem 0; |
|
|
|
|
font-family: inherit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
:global(.dark .markdown-content .greentext) { |
|
|
|
|
color: #8fbc8f; |
|
|
|
|
color: #8fbc8f; /* Lighter green for dark mode */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Ensure greentext lines appear on their own line even if markdown processes them */ |
|
|
|
|
|