Skip to content

Commit 9897e2c

Browse files
Update activecode locked and highlighted region markings on scroll
1 parent 06f8480 commit 9897e2c

1 file changed

Lines changed: 31 additions & 6 deletions

File tree

bases/rsptx/interactives/runestone/activecode/js/activecode.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,14 @@ export class ActiveCode extends RunestoneBase {
305305
editor.display.scrollbars.vert.style.bottom = "16px";
306306
});
307307
});
308+
// Update line makers on scroll. Codemirror only renders a few lines offscreen
309+
// so if locked lines are offscreen they may not get decorated
310+
CodeMirror.on(editor, "scroll", (cm) => {
311+
window.requestAnimationFrame(() => {
312+
this.setLockedRegions();
313+
this.setHighlightLines();
314+
});
315+
});
308316

309317
// Make the editor resizable
310318
let ac = this;
@@ -450,11 +458,16 @@ export class ActiveCode extends RunestoneBase {
450458
line = line.trim();
451459
let lineNum = line.split("-");
452460
if (lineNum.length > 1) {
453-
for (let i = parseInt(lineNum[0]); i <= parseInt(lineNum[1]); i++) {
461+
let startLine = parseInt(lineNum[0]) - this.editor.display.viewFrom;
462+
let endLine = parseInt(lineNum[1]) - this.editor.display.viewFrom;
463+
for (let i = startLine; i <= endLine; i++) {
454464
lines[i - 1].classList.add("CodeMirror__highlight-line");
455465
}
456466
} else {
457-
lines[lineNum - 1].classList.add("CodeMirror__highlight-line");
467+
if (lineNum > this.editor.display.viewFrom && lineNum <= this.editor.display.viewTo) {
468+
let offsetLineNum = parseInt(lineNum) - this.editor.display.viewFrom;
469+
lines[offsetLineNum - 1].classList.add("CodeMirror__highlight-line");
470+
}
458471
}
459472
});
460473
}
@@ -475,10 +488,11 @@ export class ActiveCode extends RunestoneBase {
475488
// downside is that this is not preserved on editor.refresh()
476489
// so setLockedRegions() must be called again
477490
}
478-
let midLine = Math.floor((start + end) / 2);
491+
}
492+
function placeLock(lineNumber) {
479493
var marker = document.createElement("div");
480494
marker.className = "CodeMirror__gutter-locked-marker";
481-
this.editor.setGutterMarker(midLine, "CodeMirror-lock-markers", marker);
495+
this.editor.setGutterMarker(lineNumber, "CodeMirror-lock-markers", marker);
482496
}
483497

484498
this.containerDiv.querySelectorAll(".CodeMirror-code > div").forEach(
@@ -487,11 +501,18 @@ export class ActiveCode extends RunestoneBase {
487501
}
488502
);
489503

504+
let startViewRange = this.editor.display.viewFrom;
505+
let endViewRange = this.editor.display.viewTo;
506+
490507
if (this.visiblePrefixEnd) {
491508
let lastLine = this.editor.posFromIndex(
492509
this.visiblePrefixEnd - 1
493510
).line;
494-
decorateLines.call(this, 0, lastLine);
511+
placeLock.call(this, Math.floor((0 + lastLine) / 2));
512+
let numInView = lastLine - startViewRange;
513+
if (numInView >= 0) {
514+
decorateLines.call(this, 0, numInView);
515+
}
495516
let endPos = this.editor.posFromIndex(this.visiblePrefixEnd);
496517
this.editor.markText(
497518
{ line: 0, ch: 0 },
@@ -509,7 +530,11 @@ export class ActiveCode extends RunestoneBase {
509530
this.editor.doc.getValue().length - this.visibleSuffixLength;
510531
let endPos = this.editor.posFromIndex(endIndex);
511532
let lastLine = this.editor.doc.lastLine();
512-
decorateLines.call(this, endPos.line, lastLine);
533+
placeLock.call(this, Math.floor((endPos.line + lastLine) / 2));
534+
535+
let startLine = Math.max(endPos.line - startViewRange, 0);
536+
let endLine = Math.min(lastLine - startViewRange, endViewRange);
537+
decorateLines.call(this, startLine, endLine);
513538
// include preceeding newline
514539
let endPos2 = this.editor.posFromIndex(endIndex - 1);
515540
this.editor.markText(

0 commit comments

Comments
 (0)