Preserve styles after newline

On the main prosemirror page demo, if I type in for example bold and then press enter bold is gone.

I think that is something every user expects. There’s no editor I know that doesn’t have this ‘feature’.

How can this be enabled ?

(I found this but it had no solution)

thx!

This is not a part of the splitBlock command in the default commands module, since in a semantic editing markup, where you don’t use strong as a way to give your paragraphs a different semantic meaning, this isn’t something people would do. It is quite easy to write a command that implements the behavior you’re expecting and bind that to enter.

Using the appendTransaction mechanism you can create a plugin that will grab the old marks and then ‘setStoredMarks’ on the current transaction.

I’d argue appendTransaction is the wrong place for this (since it can only inspect transactions and knows nothing about intent), and a wrapper around the splitBlock command is a better approach.

Unfortunately I don’t know how to implement this.

Considering how basic & common this is I feel it should be the default behavior with an option given to override it. The basic demo for example should definitely have this, to a newcomer it seems broken.

Otherwise can at least a correct solution be posted here ?

Any help ?

I think that is something every user expects.

I don’t agree. Actually this behaviour would annoy me! :slight_smile:

1 Like

@tl[quote=“tjvr, post:6, topic:625”] I don’t agree. Actually this behaviour would annoy me! [/quote]

Really? Your expectation is that if you hit bold, type and then hit enter, the application should auto unselect bold for you? Are there specific applications you use that behave like this?

I did a quick survey of existing web editors (tinymce, summernote, ckeditor), Prosemirror class structured editors (quill, slatejs, mobiledoc-kit, trix, draftjs), and Desktop editors (Word, TextEdit, Notes). Mobiledoc-kit and Slate behave in the same way as Prosemirror, the others preserve styles across newlines. I think it’d be surprising behavior to end users in general but I can understand the argument for keeping it as is both from a technical standpoint and just as a differentiator. Just wanted to add some more info to the conversation.

Is there anymore information on how to implement this ? How can the styles be copied from the previous line ?

This patch adds a splitBlockKeepMarks command that, after splitting the block, sets storedMarks to the set of marks that were active before the split, so that typing immediately after that will keep your marks.

Great … I still don’t get why this is not the default … 99% of users will want this …

So if I understand correctly I need to wire the newline key to call splitBlockKeepMarks ?

It would be great if the demos can be updated to use this so it’s clear how it’s done.

Thanks!

sorry, still can’t get this to work :frowning: I tried (from the basic demo):

const {EditorState} = require("prosemirror-state")
const {MenuBarEditorView} = require("prosemirror-menu")
const {DOMParser, Schema} = require("prosemirror-model")
const {schema: baseSchema} = require("prosemirror-schema-basic")
const {addListNodes} = require("prosemirror-schema-list")
const {exampleSetup} = require("prosemirror-example-setup")
const {keymap} = require("prosemirror-keymap")
const {chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlockKeepMarks} = require("prosemirror-commands");

const schema = new Schema({
  nodes: addListNodes(baseSchema.spec.nodes, "paragraph block*", "block"),
  marks: baseSchema.spec.marks
})

let view = new MenuBarEditorView(document.querySelector("#editor"), {
  state: EditorState.create({
    doc: DOMParser.fromSchema(schema).parse(""),
    plugins: exampleSetup({schema}).concat([
      keymap({ "Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlockKeepMarks) })
    ])
  })
})

But pressing Enter when bold is on still turns it off.

What am I doing wrong ?

The example setup already adds the default keymap, which binds enter. If you want to override enter, you should put your keymap before it in the array of plugins, [keymap(...)].concat(exampleSetup({schema}).

great, thx ! it finally works :slight_smile: I also submitted https://github.com/ProseMirror/prosemirror-commands/pull/3

When using splitBlockKeepMarks, any idea how to keep empty marks? As soon as I move my cursor PM seems to cleanup empty paragraphs and removes all the spans and only keep the br, here’s a video demonstrating the behavior: https://cloudup.com/ctedmMJzYU9

Couldn’t find where the cleanup happens, I’d be fine with hacking my way around so that these empty marks aren’t removed.

ProseMirror doesn’t keep empty marks—they don’t exist in the document model, and stored marks are considered to be transient, i.e. intentionally reset when the selection changes. You could write a plugin that tracks such marks, but I’m not sure it’s a great idea—it adds a piece of hidden state that isn’t visually obvious to your documents.

I understand your point. I think that it’s fair and desired when the empty mark is surrounded by text, but unexpected when in an empty paragraph, especially with splitBlockKeepMarks. Since PM is probably always used alongside a toolbar, these “hidden” states are usually illustrated with an active state on the buttons/selects.

I think we all have very different use cases for PM and valid reasons on both sides to either want to clear empty marks or keep them, but being able to choose between the two “modes” would be ideal IMO as there doesn’t seem to be a consensus.

Will explore the plugin way until then :slight_smile: