@happy-nut/monacori 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/viewer.client.js +36 -16
- package/package.json +1 -1
package/dist/viewer.client.js
CHANGED
|
@@ -509,6 +509,15 @@ function scheduleDiffScroll(row) {
|
|
|
509
509
|
// reflow-forcing scrollIntoView can run, so collapse them to one (latest element) per animation frame and
|
|
510
510
|
// use block:nearest (no per-row center-jump). Shared by the tree, source caret, and diff caret.
|
|
511
511
|
var pendingScrollEl = null, scrollElRaf = 0;
|
|
512
|
+
// Reveal `el` by keeping it ~fraction of the way down its scroller, scrolling minimally on EVERY move so the
|
|
513
|
+
// view follows the caret CONTINUOUSLY. scrollIntoView('nearest') instead leaves the view still until the
|
|
514
|
+
// caret reaches the edge and then jumps — stuttering ~every viewport while an arrow key is held.
|
|
515
|
+
function revealAt(el, scroller, fraction) {
|
|
516
|
+
if (!el) return;
|
|
517
|
+
if (!scroller || !scroller.clientHeight) { try { el.scrollIntoView({ block: 'nearest', inline: 'nearest' }); } catch (x) {} return; }
|
|
518
|
+
var off = el.getBoundingClientRect().top - scroller.getBoundingClientRect().top;
|
|
519
|
+
scroller.scrollTop += off - scroller.clientHeight * fraction;
|
|
520
|
+
}
|
|
512
521
|
function scheduleScrollIntoView(el) {
|
|
513
522
|
pendingScrollEl = el || null;
|
|
514
523
|
if (scrollElRaf) return;
|
|
@@ -897,7 +906,7 @@ function scheduleTreeFocus() {
|
|
|
897
906
|
if (treeFocusIndex < 0 || treeFocusIndex >= rows.length) return;
|
|
898
907
|
const el = rows[treeFocusIndex];
|
|
899
908
|
document.querySelectorAll('.tree-focus').forEach((e) => { if (e !== el) e.classList.remove('tree-focus'); });
|
|
900
|
-
if (el) { el.classList.add('tree-focus'); el.
|
|
909
|
+
if (el) { el.classList.add('tree-focus'); revealAt(el, document.querySelector('.sidebar-scroll'), 0.42); }
|
|
901
910
|
});
|
|
902
911
|
}
|
|
903
912
|
|
|
@@ -1583,7 +1592,7 @@ function scheduleDiffReveal(wrapper, side, ri) {
|
|
|
1583
1592
|
applyDiffSelection();
|
|
1584
1593
|
if (!t) return;
|
|
1585
1594
|
var row = diffRowAt(t.wrapper, t.side, t.ri);
|
|
1586
|
-
|
|
1595
|
+
revealAt(row, document.getElementById('diff2html-container'), 0.42);
|
|
1587
1596
|
});
|
|
1588
1597
|
}
|
|
1589
1598
|
function navEntryOf(kind) {
|
|
@@ -3318,7 +3327,7 @@ function scheduleSourceReveal(prev) {
|
|
|
3318
3327
|
var lines = f.content.split(/\r?\n/);
|
|
3319
3328
|
updateSourceCaret(p, lines, f.language || 'text');
|
|
3320
3329
|
var cl = document.querySelector('.source-row.cursor-line');
|
|
3321
|
-
|
|
3330
|
+
revealAt(cl, document.getElementById('source-body'), 0.42);
|
|
3322
3331
|
});
|
|
3323
3332
|
}
|
|
3324
3333
|
|
|
@@ -3336,25 +3345,35 @@ function updateSourceCaret(prev, lines, language) {
|
|
|
3336
3345
|
// Restore the line the caret left: drop the caret span, re-highlight the full line.
|
|
3337
3346
|
if (prev && prev.lineIndex !== viewerCursor.lineIndex) {
|
|
3338
3347
|
const prevRow = rowFor(prev.lineIndex);
|
|
3339
|
-
if (prevRow)
|
|
3340
|
-
prevRow.classList.remove('cursor-line');
|
|
3341
|
-
if (!rendered) {
|
|
3342
|
-
const prevCell = prevRow.querySelector('.source-code');
|
|
3343
|
-
if (prevCell) prevCell.innerHTML = highlightLine(lines[prev.lineIndex] || '', language);
|
|
3344
|
-
}
|
|
3345
|
-
}
|
|
3348
|
+
if (prevRow) prevRow.classList.remove('cursor-line');
|
|
3346
3349
|
}
|
|
3350
|
+
// Drop the old caret span WITHOUT re-highlighting the line — re-tokenizing a line on every caret move is
|
|
3351
|
+
// what made holding an arrow key stutter. (The diff caret already works this way: insert/remove a span.)
|
|
3352
|
+
if (!rendered) body.querySelectorAll('.code-cursor').forEach((s) => { const p = s.parentNode; if (p) { p.removeChild(s); if (p.normalize) p.normalize(); } });
|
|
3347
3353
|
// Reconcile the go-to-definition highlight (set only on symbol jumps, cleared on plain moves).
|
|
3348
3354
|
body.querySelectorAll('.source-row.symbol-target').forEach((r) => r.classList.remove('symbol-target'));
|
|
3349
3355
|
if (viewerCursor.targetLine >= 0) rowFor(viewerCursor.targetLine)?.classList.add('symbol-target');
|
|
3350
|
-
// Rebuild the new caret line with the caret span.
|
|
3351
3356
|
const row = rowFor(viewerCursor.lineIndex);
|
|
3352
3357
|
if (!row) { if (!rendered) openSourceFile(viewerCursor.path, false); return; } // line not in the DOM — full re-render (eager source only)
|
|
3353
3358
|
row.classList.add('cursor-line');
|
|
3354
|
-
if (!rendered)
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3359
|
+
if (!rendered) insertSourceCaret(row, viewerCursor.column);
|
|
3360
|
+
}
|
|
3361
|
+
// Insert the caret span at `column` of `row` via a real DOM range into the already-highlighted line — the
|
|
3362
|
+
// same cheap technique the diff caret uses, so holding an arrow key never re-tokenizes a line.
|
|
3363
|
+
function insertSourceCaret(row, column) {
|
|
3364
|
+
var cell = row.querySelector('.source-code');
|
|
3365
|
+
if (!cell || (cell.textContent || '').length === 0) return; // empty line: the cursor-line background marks it
|
|
3366
|
+
var pos = diffCaretDomPosition(cell, column);
|
|
3367
|
+
if (!pos) return;
|
|
3368
|
+
var span = document.createElement('span');
|
|
3369
|
+
span.className = 'code-cursor';
|
|
3370
|
+
span.setAttribute('aria-hidden', 'true');
|
|
3371
|
+
try {
|
|
3372
|
+
var off = pos.node.nodeType === 3 ? Math.min(pos.offset, (pos.node.textContent || '').length) : pos.offset;
|
|
3373
|
+
var range = document.createRange();
|
|
3374
|
+
range.setStart(pos.node, off); range.collapse(true);
|
|
3375
|
+
range.insertNode(span);
|
|
3376
|
+
} catch (e) {}
|
|
3358
3377
|
}
|
|
3359
3378
|
|
|
3360
3379
|
function openSourceAt(path, lineIndex, column) {
|
|
@@ -3983,6 +4002,7 @@ function openSourceFile(path, shouldSwitch = true) {
|
|
|
3983
4002
|
} else {
|
|
3984
4003
|
body.innerHTML = renderSourceTable(file, '');
|
|
3985
4004
|
if (httpEnvSelect) httpEnvSelect.classList.add('hidden');
|
|
4005
|
+
if (viewerCursor && viewerCursor.path === path) { var ccr = body.querySelector('.source-row.cursor-line'); if (ccr) insertSourceCaret(ccr, viewerCursor.column); }
|
|
3986
4006
|
}
|
|
3987
4007
|
updateRenderToggle(path);
|
|
3988
4008
|
renderSourceComments();
|
|
@@ -4518,7 +4538,7 @@ function renderSourceTable(file, query) {
|
|
|
4518
4538
|
return [
|
|
4519
4539
|
'<tr class="' + classes + '" data-line-index="' + index + '">',
|
|
4520
4540
|
'<td class="num">' + String(index + 1) + '</td>',
|
|
4521
|
-
'<td class="source-code">' +
|
|
4541
|
+
'<td class="source-code">' + highlightLine(line, file.language || 'text') + '</td>',
|
|
4522
4542
|
'</tr>',
|
|
4523
4543
|
].join('');
|
|
4524
4544
|
}).join('');
|