Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions browser/components/MarkdownPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,130 @@ class MarkdownPreview extends React.Component {
el.innerHTML = ''
el.parentNode.className += ` ${codeBlockThemeClassName}`

// Check if code block is long enough to be collapsible (15+ lines)
const lineCount = (content.match(/\n/g) || []).length + 1
const MAX_LINES_BEFORE_COLLAPSE = 15
const codeBlockContainer = el.parentNode

if (lineCount > MAX_LINES_BEFORE_COLLAPSE) {
// Add collapsible class and CSS
codeBlockContainer.classList.add('collapsible-code-block')
codeBlockContainer.classList.add('collapsed')

// Create expand/collapse button
const collapseIcon = document.createElement('button')
collapseIcon.className = 'collapse-expand-button'
collapseIcon.innerHTML = '▼'
collapseIcon.title = 'Click to expand/collapse'
collapseIcon.style.cssText = `
position: absolute;
top: 5px;
left: 5px;
z-index: 10;
border-radius: 3px;
cursor: pointer;
font-size: 10px;
width: 20px;
height: 20px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid;
`

collapseIcon.onclick = e => {
e.preventDefault()
e.stopPropagation()
if (codeBlockContainer.classList.contains('collapsed')) {
codeBlockContainer.classList.remove('collapsed')
codeBlockContainer.classList.add('expanded')
collapseIcon.innerHTML = '▲'
} else {
codeBlockContainer.classList.remove('expanded')
codeBlockContainer.classList.add('collapsed')
collapseIcon.innerHTML = '▼'
}
}

// Insert button at the beginning of the code block
codeBlockContainer.style.position = 'relative'
codeBlockContainer.appendChild(collapseIcon)

// Add inline styles for collapse behavior
if (!this.getWindow().document.getElementById('collapsible-code-styles')) {
const styleEl = document.createElement('style')
styleEl.id = 'collapsible-code-styles'
styleEl.textContent = `
.collapsible-code-block.collapsed {
max-height: 300px !important;
overflow: hidden !important;
position: relative;
}
.collapsible-code-block.collapsed::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 30px;
pointer-events: none;
}
/* Light theme gradient */
[data-theme="default"] .collapsible-code-block.collapsed::after,
[data-theme="white"] .collapsible-code-block.collapsed::after {
background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.9));
}
/* Dark theme gradient */
[data-theme="dark"] .collapsible-code-block.collapsed::after,
[data-theme="dracula"] .collapsible-code-block.collapsed::after,
[data-theme="monokai"] .collapsible-code-block.collapsed::after,
[data-theme="nord"] .collapsible-code-block.collapsed::after,
[data-theme="solarized-dark"] .collapsible-code-block.collapsed::after,
[data-theme="vulcan"] .collapsible-code-block.collapsed::after {
background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.7));
}
.collapsible-code-block.expanded {
max-height: none !important;
}
.collapsible-code-block.expanded::after {
display: none;
}
/* Button styles for light themes */
[data-theme="default"] .collapse-expand-button,
[data-theme="white"] .collapse-expand-button {
background: rgba(255, 255, 255, 0.8);
border-color: #ccc;
color: #333;
}
[data-theme="default"] .collapse-expand-button:hover,
[data-theme="white"] .collapse-expand-button:hover {
background: rgba(255, 255, 255, 0.9);
}
/* Button styles for dark themes */
[data-theme="dark"] .collapse-expand-button,
[data-theme="dracula"] .collapse-expand-button,
[data-theme="monokai"] .collapse-expand-button,
[data-theme="nord"] .collapse-expand-button,
[data-theme="solarized-dark"] .collapse-expand-button,
[data-theme="vulcan"] .collapse-expand-button {
background: rgba(0, 0, 0, 0.6);
border-color: #666;
color: #fff;
}
[data-theme="dark"] .collapse-expand-button:hover,
[data-theme="dracula"] .collapse-expand-button:hover,
[data-theme="monokai"] .collapse-expand-button:hover,
[data-theme="nord"] .collapse-expand-button:hover,
[data-theme="solarized-dark"] .collapse-expand-button:hover,
[data-theme="vulcan"] .collapse-expand-button:hover {
background: rgba(0, 0, 0, 0.8);
}
`
this.getWindow().document.head.appendChild(styleEl)
}
}

CodeMirror.runMode(content, syntax.mime, el, {
tabSize: indentSize
})
Expand Down