Move Node.fromJSON logic to Schema.nodeFromJSON

I propose moving the guts of Node.fromJSON to Schema.nodeFromJSON, to facilitate customisation of the JSON serialisation.

This way Node.fromJSON would delegate to Schema.nodeFromJSON, rather than the other way around. This would also make it more consistent with Schema.markFromJSON.

I didn’t anticipate anyone needing to customize JSON serialization. Could you tell me a little more about why you’re doing that?

We’re interested in storing documents in JSON in an idiomatic way that’s both framework and platform agnostic. Currently there’s some aspects of ProseMirror’s default JSON format that I’d like to change, for example the way mark names are encoded with "_" keys.

In my schema I may choose to only have marks that don’t have attributes, which means I could squash the encoding to be marks: ["strong", "em"].

It seems reasonable that JSON encoding should like outside Node, and Schema seems like an improvement.

Hah, it used to work that way (depending on whether the mark had attributes) but people complained that their JSON schemas didn’t handle that.

So the idea is to subclass Schema in order to do this? That does seem rather random. Have you considered simply writing your own JSON serializer entirely separately from ProseMirror’s built-in mechanisms? It’s only a handful of lines anyway.

Ooo interesting, I didn’t realise JSON schema would have that limitation. Thanks for the background, I’ll do some exploring in that area.

Good point, and I actually prefer this approach more. Decoupling things that don’t really need to be coupled makes sense. It’s a trade of convenience vs flexibility, but in this case I’d probably prefer to see all the JSON serialisation/deserialisation stuff removed from Schema and Node, and put in some a marshalling utility package.

Having a toJSON + a static fromJSON method on the types itself works well and makes these easy to place and find. I guess you’re right that the situation with Marks is a bit of a mess. I’ll move that logic to the Mark class as well.

See this patch. I kept Schema.markFromJSON and Schema.nodeFromJSON because they are pre-bound to the Schema and thus useful for mapping over arrays of JSON stuff without allocating closures.

1 Like