Updating the viewport when the height of visible lines changes dramatically

As always, thanks for all your hard work on CodeMirror! We’re watching progress on CM.next with great interest.

I’m working on a system where every top-level expression is replaced by a widget, so there is no actual text displayed by CodeMirror. A widget, for example, might represent 20-30 lines of code, and the CM viewport might only display 3-4 such widgets.

For long expressions that span many lines, these widgets can be quite complex, and take up a lot of vertical space. We also have the ability to collapse a widget, hiding its contents and consuming only a line-height’s worth of vertical space. We also have a CollapseAll shortcut, which immediately collapses all widgets.

When we CollapseAll, the combined vertical size of the widgets shrinks dramatically and the range of text represented by those widgets grows proportionally. We’d expect to see lots more widgets appear in the viewport, as a result. However, CM only shows the widgets that were previously visible, with blank space shown where the other collapsed widgets should be. When I fire up the DOM inspector, it looks like CodeMirror-lines is still showing only the previously-visible lines, so somehow I need to notify CM that the display has changed and it should recalculate what lines are in the viewport. Calling cm.refresh() does not fix the issue.

I can confirm that clicking anywhere in the CM display instantly fixes the issue, so there must be some event that fires onClick that I need to fire when collapseAll is called. I’m pretty familiar with the manual at this point, and I’ve been re-reading it carefully to see if I missed something. Is the solution hiding in plain sight? :slight_smile:

Have you tried calling the changed() method on the widget mark when its content changes?

Damn, you’re fast. :wink:

I haven’t, but that may also be because I’m misunderstanding what “its content changes” means. Previously I’d always assumed that mean the DOM tree changes in some way, but it sounds like you’re suggesting that even a CSS or attribute change would qualify?

(I won’t go into detail on why calling changed() on the widget is hard on my end. Just wondering if I’m interpreting the behavior of that method correctly before I put in the elbow grease)

headdesk Yup, I’ve been misinterpreting. It’s right there (of course!) in the docs: *Call this if you made some change to the widget’s DOM node that might affect its height. *

You’d think after hacking on CM all these years I wouldn’t have missed that…

Sorry, Marijn. You have the patience of a saint.