Meta Data Nodes

In my schema there is a node that contains meta data. The node is not visible and should not be editable/deletable by the user. Normally I would not include the meta data in the document but an external system generates files with meta data nodes that are then ingested by the prosemirror editor.

I’ve been able to make these meta data nodes read-only up to this point. But thanks to the help of @JCHollett I’ve discovered that selecting all and then deleting will remove the meta data nodes.

One solution is to completely pull the meta data out of the document before giving it to the prosemirror editor. The main reason I have not done this is that collaborative editors can make changes that update the meta data that then need to be merged into the document. Keeping the meta data in the document means the prosemirror collaborative authority takes care of that merging for me.

Is there any way to make a node completely un-editable by the user?

You can override the Ctrl/Cmd-A binding, but then you reintroduce the problems that it was introduced to handle (not being able to select leaf block nodes at the start/end of the document because you can’t create a DOM selection over them).

I would really recommend putting only the visible, editable part of the document into the editor. I’m not sure how you are hiding the metadata, but if it’s in the form of display: none DOM nodes, I expect there may be other situations in which browsers allow the user to mess with them.

My metadata has no text content, only nodes and attributes. So it has a height of 0px in the dom.

That being the case I’ll investigate adding a pre-processing phase when creating a collaborative document.

Thanks for your input Marijn.

One thing you can do to hide this node in the dom is to leave it as a textNode by just leaving the nodespec for toDOM = function(){return “”;}. It is nearly invisible this way when its just inside the doc node and no deeper. It is also possible to just have a contenteditable = false node in the structure and let it render and have no “content hole” and all the metadata is invisible besides that root node. Especially if you only use attributes in this system. Attributes do not have to be rendered in the dom.

It may be sufficient to add some handler for keeping this data outside the model sure. But, I cannot speak for that part of the collab system in our case. My understanding was that it was easier for our use case to do it this way.

@mikeb or @jon, Anything you might like to add to this?

When I tried implementing document attributes that could be serialized to storage and sync’d across collab before, I wound up using this fake ‘metadata’ node since document attributes weren’t a possibility.

What I’ve found in testing is that you can define attributes on the document okay and they initialize to default values. The problem is there’s no way within the current setNodeMarkup transform model to change the document’s attributes in that manner; it transforms the children of the doc I believe.

Right, the existing steps can only change the content of the document—since the position coordinate system starts and ends inside of the document, you can’t address the top node. It is possible to define a custom step type to set document attributes. It might actually be a good idea to add such a step to prosemirror-transform by default.

1 Like

I think it might be a good idea to also have that top node being able to have some attributes set to it just incase you want classes to change and whatnot. I imagine that would be the normal use case.

One question we had in our chat though was how the rendering would handle the replaceAround the doc. My thought was that it wouldn’t delete the node and redo it.

You can’t replace around the doc. Also the doc node isn’t rendered, just its content.