Ignored/Non-selectable Managed Content

I have a figure node which is managed outside of ProseMirror (clicking on it opens a modal). I want these figures to exist within the editor div but basically be ignored with respect to normal editing. Things like selecting, deleting & copying should all ignore the figure.

This may sound crazy but starts to make sense when dealing with floats.

Document Node Order:

<p>Text Above Figure</p>
<figure></figure>
<p>Text Below Figure</p>

Appearance

Text Above Figure
Text Below Figure      [figure]

Here, it’s a bit awkward that [figure] is in between the two paragraphs. It is non-intuitive that having your cursor at the beginning of “Text Below Figure” and hitting backspace will delete the figure. Or that highlighting text across these two paragraphs will also select the figure.

For these reasons I’d like to figure out a way to just completely ignore figures when it comes to editing. Could I add an editable or isIgnored to the node model? What places would have to take this into account? My gut tells me this is way too involved as every operation would have to skip over these nodes.

Thoughts? Would appreciate any help on this! Thanks!

1 Like

Interesting use case. I have no idea how to address it, though. As you say, making exceptions in all commands doesn’t seem like a very nice route. You could make most selection-related commands ignore these by making them non-selectable. Maybe the amount of problematic commands that leaves is relatively small, and you could just replace those with extended versions in your code? (Which still might not be trivial to write.)

This is interesting, but I don’t completely understand the scenario you’re describing — it seems artificial and I don’t really understand it.

Do you imagine there’d be any way to interact with the figure? I assume you could click on it or something? but it’d remain inaccessible when using the keyboard only?

I think any scenario involving floats sitting next to other content will encounter this. The visual appearance of the content hides a bit of where the floated content is inserted (where the node is as outlined in my original post).

Do you imagine there’d be any way to interact with the figure? I assume you could click on it or something? but it’d remain inaccessible when using the keyboard only?

Yep! I have a click handler that opens a modal to manage the image figure.

I’ll probably explore adding ignoring these figures upon selection and forward/backward deletion.

For posterity, the cases that need to be handled:

  • Backspace - backwards delete
  • Ctrl-D - forwards delete
  • Highlight
    • delete
    • copy
    • paste
    • drag & drop
    • entering text
    • hitting enter
    • hitting shfit-enter (hard-break)

@wes-r is your use case comparable to that one ? https://kapouer.github.io/coed/demo/index.html

you can insert an url, and also move and select the blocks using the left column inside them. The center part is editable, and not the left and right parts.

Looks like those blocks have editable and non editable content but the blocks themselves are still editable within the document. What I needed was a way to have blocks exist within the document that can only be added & removed by an external interface. So any highlighting/backspacing deleting/replacing/etc should not remove these special blocks.

Is there a recommended solution to it now (as of 2022)?

What I was trying to use was filterTransaction which worked great when trying to delete just the ignored figure. The problem comes when the ignored node is part of a bigger selection (eg figure + some paragraph) then I would expect to have everything deleted except for the ignored node. For this scenario, I tried combining filterTransaction which stops applying the transaction and then running appendTransaction which could remove only the non-ignored nodes by running tr.deleteRange with all the ranges except for the ignored node range. All the ranges can be stored in the plugin state.

The issue here is that since filterTransaction stops the actual transaction from being applied the appendTransaction is not triggered. Is there a way to populate a new transaction from filterTransaction?

1 Like

This is not something the library currently supports. See this RFC discussion.

1 Like

This idea of a replaceTransaction I think would be quite powerful, if also dangerous. I wonder if there’s any interest in implementing it or if it’s a dead proposal now?