Skip to content

Commit d82add0

Browse files
ziadziad
authored andcommitted
* make blocks collapsible,
* work on branch tables
1 parent f5c6fb3 commit d82add0

7 files changed

Lines changed: 418 additions & 49 deletions

File tree

playground/explorer/function-renderer.ts

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,19 +185,96 @@ export function renderFunctionDetail(context: DetailContext, funcIndex: number):
185185
const block = document.createElement('div');
186186
block.className = 'detail-code';
187187
const lines = decompiledCode.split('\n');
188+
189+
// Match every opening { to its closing }
190+
const bracePairs = new Map<number, number>();
191+
const braceStack: number[] = [];
192+
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
193+
const stripped = lines[lineIdx].trim();
194+
if (stripped.startsWith('}')) {
195+
if (braceStack.length > 0) {
196+
bracePairs.set(braceStack.pop()!, lineIdx);
197+
}
198+
}
199+
if (stripped.endsWith('{')) {
200+
braceStack.push(lineIdx);
201+
}
202+
}
203+
188204
const gutterWidth = String(lines.length).length;
205+
206+
const lineElements: HTMLElement[] = [];
207+
const foldCollapsed = new Set<number>();
208+
189209
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
190210
const lineEl = document.createElement('div');
191211
lineEl.className = 'code-line';
212+
213+
const foldSlot = document.createElement('span');
214+
foldSlot.className = 'code-fold-slot';
215+
216+
const closingLine = bracePairs.get(lineIdx);
217+
const isFoldable = closingLine !== undefined && closingLine - lineIdx > 1;
218+
219+
let ellipsis: HTMLSpanElement | null = null;
220+
if (isFoldable) {
221+
foldSlot.classList.add('foldable');
222+
foldSlot.textContent = '\u25BE';
223+
224+
const openIdx = lineIdx;
225+
const closeIdx = closingLine;
226+
const hiddenCount = closeIdx - openIdx - 1;
227+
228+
ellipsis = document.createElement('span');
229+
ellipsis.className = 'code-fold-ellipsis';
230+
ellipsis.textContent = `\u2026 ${hiddenCount} lines`;
231+
ellipsis.style.display = 'none';
232+
ellipsis.addEventListener('click', () => {
233+
foldSlot.click();
234+
});
235+
236+
foldSlot.addEventListener('click', () => {
237+
const wasCollapsed = foldCollapsed.has(openIdx);
238+
if (wasCollapsed) {
239+
foldCollapsed.delete(openIdx);
240+
} else {
241+
foldCollapsed.add(openIdx);
242+
}
243+
const isNowCollapsed = foldCollapsed.has(openIdx);
244+
ellipsis!.style.display = isNowCollapsed ? '' : 'none';
245+
foldSlot.textContent = isNowCollapsed ? '\u25B8' : '\u25BE';
246+
for (let targetLine = openIdx + 1; targetLine < closeIdx; targetLine++) {
247+
let shouldHide = false;
248+
for (const collapsedOpen of foldCollapsed) {
249+
const collapsedClose = bracePairs.get(collapsedOpen);
250+
if (collapsedClose !== undefined && targetLine > collapsedOpen && targetLine < collapsedClose) {
251+
shouldHide = true;
252+
break;
253+
}
254+
}
255+
lineElements[targetLine].style.display = shouldHide ? 'none' : '';
256+
}
257+
});
258+
}
259+
192260
const gutter = document.createElement('span');
193261
gutter.className = 'code-line-number';
194-
gutter.textContent = String(lineIdx + 1).padStart(gutterWidth, ' ');
262+
gutter.textContent = String(lineIdx + 1).padStart(gutterWidth);
195263
lineEl.appendChild(gutter);
196-
const content = document.createElement('span');
197-
content.className = 'code-line-content';
198-
renderHighlightedC(content, lines[lineIdx], highlightOptions);
199-
lineEl.appendChild(content);
264+
265+
lineEl.appendChild(foldSlot);
266+
267+
const lineContent = document.createElement('span');
268+
lineContent.className = 'code-line-content';
269+
renderHighlightedC(lineContent, lines[lineIdx], highlightOptions);
270+
lineEl.appendChild(lineContent);
271+
272+
if (ellipsis) {
273+
lineEl.appendChild(ellipsis);
274+
}
275+
200276
block.appendChild(lineEl);
277+
lineElements.push(lineEl);
201278
}
202279
const wrapper = document.createElement('div');
203280
wrapper.className = 'detail-block-wrapper';

playground/explorer/ui-helpers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,13 @@ export function appendCodeBlock(parent: HTMLElement, code: string): void {
189189

190190
const lines = code.split('\n');
191191
const gutterWidth = String(lines.length).length;
192-
193192
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
194193
const lineElement = document.createElement('div');
195194
lineElement.className = 'code-line';
196195

197196
const gutter = document.createElement('span');
198197
gutter.className = 'code-line-number';
199-
gutter.textContent = String(lineIndex + 1).padStart(gutterWidth, ' ');
198+
gutter.textContent = String(lineIndex + 1).padStart(gutterWidth);
200199
lineElement.appendChild(gutter);
201200

202201
const content = document.createElement('span');

playground/index.html

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,27 +1110,62 @@
11101110

11111111
.code-line {
11121112
display: flex;
1113-
padding: 0 16px;
1113+
padding: 0 16px 0 0;
11141114
}
11151115

11161116
.code-line:hover { background: rgba(30, 30, 46, 0.8); }
11171117

11181118
.code-line-number {
11191119
color: #45475a;
1120-
text-align: right;
1121-
padding-right: 16px;
1122-
min-width: 4ch;
1120+
white-space: pre;
1121+
padding-left: 12px;
1122+
padding-right: 12px;
11231123
user-select: none;
11241124
flex-shrink: 0;
1125-
flex-grow: 0;
11261125
border-right: 1px solid #313244;
1127-
margin-right: 16px;
11281126
font-family: inherit;
11291127
font-variant-numeric: tabular-nums;
11301128
}
11311129

1130+
.code-fold-slot {
1131+
width: 18px;
1132+
flex-shrink: 0;
1133+
text-align: center;
1134+
font-size: 11px;
1135+
color: #585b70;
1136+
user-select: none;
1137+
line-height: inherit;
1138+
visibility: hidden;
1139+
}
1140+
1141+
.code-fold-slot.foldable {
1142+
cursor: pointer;
1143+
visibility: visible;
1144+
}
1145+
1146+
.code-fold-slot.foldable:hover {
1147+
color: #cdd6f4;
1148+
}
1149+
11321150
.code-line-content { white-space: pre; }
11331151

1152+
.code-fold-ellipsis {
1153+
color: #7f849c;
1154+
background: #1e1e2e;
1155+
border: 1px solid #313244;
1156+
border-radius: 4px;
1157+
padding: 0 6px;
1158+
margin-left: 8px;
1159+
font-size: 11px;
1160+
cursor: pointer;
1161+
user-select: none;
1162+
}
1163+
1164+
.code-fold-ellipsis:hover {
1165+
color: #cdd6f4;
1166+
border-color: #45475a;
1167+
}
1168+
11341169
.detail-block-wrapper { position: relative; }
11351170

11361171
.detail-copy-btn {

0 commit comments

Comments
 (0)