Hiding many nodes with Decorations?

I’m working on editor where I can tag a custom node type Page which can be related to one or more Topics.

I’ve instrumented a Prosemirror editor with a custom schema. A Page has an optional attribute topics with an array of topic IDs.

I’d like to be able to filter down visible nodes to a particular topic. I wonder what approaches I should consider for this.

An option I am considering:

I keep a list of document ranges which should be hidden. When I click a button to show only posts from topic 1, iterate over the document to collect ranges for Pages that are not related to that topic. Then, in a plugin that provides decorations, create a decoration for each range that hides the unrelated Page element with CSS. These ranges would be updated whenever a new transaction occurs.

I could also move the selection out of hidden ranges if the selection enters one, as suggested previously. In prototyping I noticed the selection moves over hidden selections okay in Chrome on a Mac, but I bet cross-browser testing would find bugs in this approach without a selection management implementation.

Is this a good use case for decorations? I wonder if this approach would introduce performance issues. Say with 500 Pages, if I create 450 decorations on each key press would slow down editing? And if there are other approaches I should consider.


Hey, it may depend a bit on the number of pages and topics, but in general, I would think it will be easier to add the topic IDs as classes on each individual page and then add a stylesheet to the document that you update dynamically in JavaScript in which you list the page topics that you want to hide/show currently. I don’t know what they will depend on, but say you make them dependent on user input into a search field or checkboxes the user can click or some such thing, and so whenever the list is updated, all you have to do is change the contents of that stylesheet.

Absolutely. If you are a bit careful about the way you update them, a few thousand decorations shouldn’t be a performance issue at all.

This seems like it might also be possible to do with a custom node view for your Page node that used plugin state to draw or not based on which Topics were currently shown/hidden in the plugin state. You could even draw a little placeholder icon that PM would be able to move around to indicate there are hidden topics.

If you are a bit careful about the way you update them, a few thousand decorations shouldn’t be a performance issue at all.

How do you mean “careful about the way you update them”? Should I be caching Decorations somehow rather than recreating them in a plugin’s decorations() method, or ?

I just found this comment about Decorations performance that I’ll look into.

I’d make sure to at least put them in a state field so that you don’t have to recompute them on updates where the document (or collapse state) didn’t change. Whether it’s worth trying to incrementally update them only around document changes I’m not sure — probably not. Profile and see.