@@ -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