@@ -9,7 +9,7 @@ document.addEventListener("DOMContentLoaded", function () {
99
1010 // View Mode State - Story 1.1
1111 let currentViewMode = 'split' ; // 'editor', 'split', or 'preview'
12- const APP_VERSION = '3.6.1 ' ;
12+ const APP_VERSION = '3.6.2 ' ;
1313 let activeModal = null ;
1414 let lastFocusedElement = null ;
1515 let isFindModalOpen = false ;
@@ -3631,36 +3631,68 @@ This is a fully client-side application. Your content never leaves your browser
36313631 return Math . max ( 1 , Math . round ( contentHeight / lineHeight ) ) ;
36323632 }
36333633
3634+ const lineCache = new Map ( ) ;
3635+ let lastEditorWidth = 0 ;
3636+
36343637 function updateLineNumbers ( ) {
36353638 if ( ! lineNumbers || ! markdownEditor ) return ;
36363639 const lines = ( markdownEditor . value || '' ) . split ( '\n' ) ;
36373640 const lineCount = Math . max ( 1 , lines . length ) ;
3641+
3642+ // Clear height cache if editor width has changed
3643+ const currentWidth = markdownEditor . clientWidth ;
3644+ if ( currentWidth !== lastEditorWidth ) {
3645+ lineCache . clear ( ) ;
3646+ lastEditorWidth = currentWidth ;
3647+ }
3648+
36383649 updateLineNumberGutter ( lineCount ) ;
36393650 ensureLineNumberMeasure ( ) ;
36403651 const styles = window . getComputedStyle ( markdownEditor ) ;
36413652 const lineHeight = getLineHeight ( styles ) ;
36423653 const paddingSum =
36433654 ( parseFloat ( styles . paddingTop ) || 0 ) +
36443655 ( parseFloat ( styles . paddingBottom ) || 0 ) ;
3656+
36453657 const existingItems = lineNumbers . children ;
3646- if ( existingItems . length !== lineCount ) {
3658+ const existingCount = existingItems . length ;
3659+
3660+ // Adjust the number of DOM elements in-place to avoid complete tear-down
3661+ if ( existingCount < lineCount ) {
36473662 const fragment = document . createDocumentFragment ( ) ;
3648- lines . forEach ( function ( line , index ) {
3663+ for ( let i = existingCount ; i < lineCount ; i += 1 ) {
36493664 const lineNumber = document . createElement ( 'div' ) ;
36503665 lineNumber . className = 'line-number' ;
3651- lineNumber . textContent = index + 1 ;
3652- const wrapCount = getWrappedLineCount ( line , lineHeight , paddingSum ) ;
3653- lineNumber . style . height = `${ wrapCount * lineHeight } px` ;
36543666 fragment . appendChild ( lineNumber ) ;
3655- } ) ;
3656- lineNumbers . textContent = '' ;
3667+ }
36573668 lineNumbers . appendChild ( fragment ) ;
3658- } else {
3659- for ( let i = 0 ; i < lineCount ; i += 1 ) {
3660- const wrapCount = getWrappedLineCount ( lines [ i ] , lineHeight , paddingSum ) ;
3661- existingItems [ i ] . style . height = `${ wrapCount * lineHeight } px` ;
3669+ } else if ( existingCount > lineCount ) {
3670+ while ( lineNumbers . children . length > lineCount ) {
3671+ lineNumbers . removeChild ( lineNumbers . lastChild ) ;
3672+ }
3673+ }
3674+
3675+ // Update only the heights and numbers that changed, querying cache
3676+ for ( let i = 0 ; i < lineCount ; i += 1 ) {
3677+ const lineText = lines [ i ] ;
3678+ let wrapHeight = lineCache . get ( lineText ) ;
3679+ if ( wrapHeight === undefined ) {
3680+ const wrapCount = getWrappedLineCount ( lineText , lineHeight , paddingSum ) ;
3681+ wrapHeight = wrapCount * lineHeight ;
3682+ lineCache . set ( lineText , wrapHeight ) ;
3683+ }
3684+
3685+ const item = existingItems [ i ] ;
3686+ const targetText = String ( i + 1 ) ;
3687+ if ( item . textContent !== targetText ) {
3688+ item . textContent = targetText ;
3689+ }
3690+ const targetHeight = `${ wrapHeight } px` ;
3691+ if ( item . style . height !== targetHeight ) {
3692+ item . style . height = targetHeight ;
36623693 }
36633694 }
3695+
36643696 syncLineNumberScroll ( ) ;
36653697 }
36663698
@@ -5868,4 +5900,15 @@ This is a fully client-side application. Your content never leaves your browser
58685900 container . appendChild ( toolbar ) ;
58695901 } ) ;
58705902 }
5903+
5904+ // Register Service Worker for offline capabilities
5905+ if ( 'serviceWorker' in navigator ) {
5906+ window . addEventListener ( 'load' , function ( ) {
5907+ navigator . serviceWorker . register ( 'sw.js' ) . then ( function ( registration ) {
5908+ console . log ( 'ServiceWorker registration successful with scope: ' , registration . scope ) ;
5909+ } , function ( err ) {
5910+ console . log ( 'ServiceWorker registration failed: ' , err ) ;
5911+ } ) ;
5912+ } ) ;
5913+ }
58715914} ) ;
0 commit comments