Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EditorState::reconfigure with a different schema instance can leave the document in a broken state #754

Closed
5id opened this issue Jan 17, 2018 · 2 comments

Comments

@5id
Copy link

5id commented Jan 17, 2018

Issue details

I'm currently working on supporting switching between different "appearances" around a PM editor in React. i.e. going from a short-form editor to a full page width editor.

It's gone pretty well, and I've taken a bit of inspiration from the various React-PM approaches.

Since we're leaning into react, we're trying to make everything as stateless and prop-dependent as we can - the way we're currently doing this is:

  1. Generate the schema from an list of PluginAbstractions (they declare the Plugins & what nodes/marks they require), e.g. for image it provides both the image plugin & the nodes for image
  2. Create the editor state from the schema and the list of Plugins

This doesn't work as expected when doing:

const state = new EditorState({ schema: oldSchema, doc, plugins });
const newState = state.reconfigure({ schema: newSchema, plugins });

newState.doc will end up still holding a reference to the original schema

Steps to reproduce

  1. open https://fascinated-heart.glitch.me/
  2. try and edit any of the lines and see that they'll blank out

(code is available here: https://glitch.com/edit/#!/fascinated-heart )

ProseMirror version

Latest / ^1.0.0

Affected platforms

All

Screenshots / Screencast (Optional)

Gif of this here

Suspected Why?

Because the nodes between the Schemas are not the same object reference, when transforms/transactions are applied it doesn't know how to handle the type of the document.

@marijnh
Copy link
Member

marijnh commented Jan 17, 2018

Yeah, schemas have identity—for performance reasons, the NodeType and MarkType objects are compared by pointer rather than by content, so trying to use a document with an identical but newly created schema will break. I agree that this can be inconvenient, but the complexity required to remove the restriction seems more problematic than the restriction itself, so I don't think this is going to change.

@5id
Copy link
Author

5id commented Jan 17, 2018

👍 at the least, it's now been flagged so future folks will understand what's going on if they come across a similar issue around this.

The workaround is fairly simple - it's not as performant as it could be, though it's not a big issue given how rarely such a change should occur:

const editorState = prevState.editorState.reconfigure({ schema, plugins });
editorState.doc = schema.nodeFromJSON(editorState.doc.toJSON());

I'd be happy to raise a PR to extend the current docs for reconfigure to include a disclaimer around this, i.e.

Create a new state based on this one, but with an adjusted set of active plugins. State fields that exist in both sets of plugins are kept unchanged. Those that no longer exist are dropped, and those that are new are initialized using their init method, passing in the new configuration object. Schema nodes and marks should persist across schema changes as a semantically identical but newly created schema may cause issues with document editing.

@5id 5id closed this as completed Feb 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants