@@ -497,8 +497,12 @@ window.CodeMirror = (function() {
497497 }
498498 var diff = node . lineObj . height - height ;
499499 if ( height < 2 ) height = textHeight ( display ) ;
500- if ( diff > .001 || diff < - .001 )
500+ if ( diff > .001 || diff < - .001 ) {
501501 updateLineHeight ( node . lineObj , height ) ;
502+ var widgets = node . lineObj . widgets ;
503+ if ( widgets ) for ( var i = 0 ; i < widgets . length ; ++ i )
504+ widgets [ i ] . height = widgets [ i ] . node . offsetHeight ;
505+ }
502506 }
503507 display . viewOffset = heightAtLine ( cm , getLine ( doc , from ) ) ;
504508 // Position the mover div to align with the current virtual scroll position
@@ -978,7 +982,7 @@ window.CodeMirror = (function() {
978982 // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
979983 function intoCoordSystem ( cm , lineObj , rect , context ) {
980984 if ( lineObj . widgets ) for ( var i = 0 ; i < lineObj . widgets . length ; ++ i ) if ( lineObj . widgets [ i ] . above ) {
981- var size = lineObj . widgets [ i ] . node . offsetHeight ;
985+ var size = widgetHeight ( lineObj . widgets [ i ] ) ;
982986 rect . top += size ; rect . bottom += size ;
983987 }
984988 if ( context == "line" ) return rect ;
@@ -2597,25 +2601,10 @@ window.CodeMirror = (function() {
25972601 } ) ,
25982602
25992603 addLineWidget : operation ( null , function ( handle , node , options ) {
2600- var widget = options || { } ;
2601- widget . node = node ;
2602- if ( widget . noHScroll ) this . display . alignWidgets = true ;
2603- changeLine ( this , handle , function ( line ) {
2604- ( line . widgets || ( line . widgets = [ ] ) ) . push ( widget ) ;
2605- widget . line = line ;
2606- return true ;
2607- } ) ;
2608- return widget ;
2604+ return addLineWidget ( this , handle , node , options ) ;
26092605 } ) ,
26102606
2611- removeLineWidget : operation ( null , function ( widget ) {
2612- var ws = widget . line . widgets , no = lineNo ( widget . line ) ;
2613- if ( no == null || ! ws ) return ;
2614- for ( var i = 0 ; i < ws . length ; ++ i ) if ( ws [ i ] == widget ) ws . splice ( i -- , 1 ) ;
2615- var newHeight = widget . node . offsetHeight ? widget . line . height - widget . node . offsetHeight : textHeight ( this . display ) ;
2616- updateLineHeight ( widget . line , newHeight ) ;
2617- regChange ( this , no , no + 1 ) ;
2618- } ) ,
2607+ removeLineWidget : function ( widget ) { widget . remove ( ) ; } ,
26192608
26202609 lineInfo : function ( line ) {
26212610 if ( typeof line == "number" ) {
@@ -3587,6 +3576,59 @@ window.CodeMirror = (function() {
35873576 line . markedSpans = spans ;
35883577 }
35893578
3579+ // LINE WIDGETS
3580+
3581+ var LineWidget = CodeMirror . LineWidget = function ( cm , node , options ) {
3582+ for ( var opt in options ) if ( options . hasOwnProperty ( opt ) )
3583+ this [ opt ] = options [ opt ] ;
3584+ this . cm = cm ;
3585+ this . node = node ;
3586+ } ;
3587+ function widgetOperation ( f ) {
3588+ return function ( ) {
3589+ startOperation ( this . cm ) ;
3590+ try { var result = f . apply ( this , arguments ) ; }
3591+ finally { endOperation ( this . cm ) ; }
3592+ return result ;
3593+ } ;
3594+ }
3595+ LineWidget . prototype . clear = widgetOperation ( function ( ) {
3596+ var ws = this . line . widgets , no = lineNo ( this . line ) ;
3597+ if ( no == null || ! ws ) return ;
3598+ for ( var i = 0 ; i < ws . length ; ++ i ) if ( ws [ i ] == this ) ws . splice ( i -- , 1 ) ;
3599+ updateLineHeight ( this . line , Math . max ( 0 , this . line . height - widgetHeight ( this ) ) ) ;
3600+ regChange ( this . cm , no , no + 1 ) ;
3601+ } ) ;
3602+ LineWidget . prototype . changed = widgetOperation ( function ( ) {
3603+ var oldH = this . height ;
3604+ this . height = null ;
3605+ var diff = widgetHeight ( this ) - oldH ;
3606+ if ( ! diff ) return ;
3607+ updateLineHeight ( this . line , this . line . height + diff ) ;
3608+ var no = lineNo ( this . line ) ;
3609+ regChange ( this . cm , no , no + 1 ) ;
3610+ } ) ;
3611+
3612+ function widgetHeight ( widget ) {
3613+ if ( widget . height != null ) return widget . height ;
3614+ if ( ! widget . node . parentNode )
3615+ removeChildrenAndAdd ( widget . cm . display . measure , elt ( "div" , [ widget . node ] , null , "position: relative" ) ) ;
3616+ return widget . height = widget . node . offsetHeight ;
3617+ }
3618+
3619+ function addLineWidget ( cm , handle , node , options ) {
3620+ var widget = new LineWidget ( cm , node , options ) ;
3621+ if ( widget . noHScroll ) cm . display . alignWidgets = true ;
3622+ changeLine ( cm , handle , function ( line ) {
3623+ ( line . widgets || ( line . widgets = [ ] ) ) . push ( widget ) ;
3624+ widget . line = line ;
3625+ if ( ! lineIsHidden ( line ) || widget . showIfHidden )
3626+ updateLineHeight ( line , line . height + widgetHeight ( widget ) ) ;
3627+ return true ;
3628+ } ) ;
3629+ return widget ;
3630+ }
3631+
35903632 // LINE DATA STRUCTURE
35913633
35923634 // Line objects. These hold state related to a line, including
0 commit comments