@@ -409,17 +409,19 @@ export const deleteDocBlock = StateEffect.define<{ from: number }>({
409409// Create a [widget](https://codemirror.net/docs/ref/#view.WidgetType) which
410410// contains a doc block.
411411class DocBlockWidget extends WidgetType {
412+ dom : null | HTMLDivElement ;
412413 constructor (
413414 readonly indent : string ,
414415 readonly delimiter : string ,
415416 readonly contents : string ,
417+ dom : null | HTMLDivElement
416418 // Only used in an update to avoid changing an already-modified doc
417419 // block.
418- readonly dom : null | HTMLDivElement ,
419420 ) {
420421 // TODO: I don't understand why I don't need to store the provided
421422 // parameters in the object: `this.indent = indent;`, etc.
422423 super ( ) ;
424+ this . dom = dom ;
423425 }
424426
425427 eq ( other : DocBlockWidget ) {
@@ -446,6 +448,7 @@ class DocBlockWidget extends WidgetType {
446448 this . contents +
447449 "</div>" ;
448450 mathJaxTypeset ( wrap ) ;
451+ this . dom = wrap ;
449452 return wrap ;
450453 }
451454
@@ -473,6 +476,7 @@ class DocBlockWidget extends WidgetType {
473476 contents_div . innerHTML = this . contents ;
474477 mathJaxTypeset ( contents_div ) ;
475478 }
479+ this . dom = dom as HTMLDivElement ;
476480
477481 // Indicate the update was successful.
478482 return true ;
@@ -502,6 +506,7 @@ class DocBlockWidget extends WidgetType {
502506 const tinymce_div = document . getElementById ( "TinyMCE-inst" ) ! ;
503507 codechat_body . insertBefore ( tinymce_div , null ) ;
504508 }
509+ this . dom = null ;
505510 }
506511}
507512
@@ -620,7 +625,28 @@ const on_dirty = (
620625export const DocBlockPlugin = ViewPlugin . fromClass (
621626 class {
622627 constructor ( view : EditorView ) { }
623- update ( update : ViewUpdate ) { }
628+ update ( update : ViewUpdate ) {
629+ // If the editor doesn't have focus, ignore selection changes. This
630+ // avoid the case where cursor movement in the IDE produces
631+ // selection changes in the Client, which then steals focus. TODO:
632+ // with the editor isn't focused, highlight the relevant line or
633+ // something similar.
634+ if ( update . selectionSet && update . view . hasFocus ) {
635+ // See if the new main selection falls within a doc block.
636+ const main_selection = update . state . selection . main ;
637+ update . state
638+ . field ( docBlockField )
639+ . between (
640+ main_selection . from ,
641+ main_selection . to ,
642+ ( from : number , to : number , value : Decoration ) => {
643+ // If so, give focus to the contents of the doc
644+ // block.
645+ value . spec . widget . dom ?. childNodes [ 1 ] . focus ( ) ;
646+ } ,
647+ ) ;
648+ }
649+ }
624650 } ,
625651 {
626652 eventHandlers : {
0 commit comments