Does ProseMirror match my editor requirements?

The last few days I was searching for an editor with this requirements:

  • multiple edit instances for p, h*, ul
  • no additional wrapping inside or ouside those tags in edit mode
  • restrict inline tags for each instance. e.g. p -> b/i/br, ul -> b/i/a/li, h1 only edit or h1 -> b/i/br
  • fine grade control over return: nothing happens, new li or br
  • air mode (pop up menu)

Most editors do some disturbing wrapping which destroys the wysywyg experience. I did check the last few days froala, redactor, quill and prosemirror.

ProseMirror seems to be promising as it’s made for customizing. I started to read the docu and inspected some code of prosemirror but I still can not answer my questions above. Maybe an experienced prosemirror developer knows instantly if this might be possible or no way around.

Hope I can continue the story and dive deeper into the word of ProseMirror.

You can definitely get fine grade control over the enter keystrokes including all keystrokes.

You can definitely get pop up menus made with JSX.

You can definitely tell this what inline content is allowed for each type of Node.

Not sure what you mean by additional wrapping. It wraps what you set it up to wrap or not wrap in whatever kind of tags you want.

You can create Nodes that use the same kind of tag 70 times if you want, for any type of tag.

I’ve been using prosemirror for 7-8 months now to create an editor with rigid rules and pagination, collab editting, etc. It is not for the feint of heart, but you can make it do whatever you want in my experience. But like I said, you basically have to be ready to drop serious time. There is a learning curve.

Good news, thank you!

Example

before edit: <h1>Hello world</h3>
edit mode: <div class"whatever"><h1><div class="another">Hello, world</div></h1></div>

Most editors do some disturbing wrapping which does influence wysywyg experience of editable area.

Restricted to each node type or same node type (e.g. p) but differently initialized? I try to explain (has nothing to do with ProseMirror Code)

  • new Edit({ dom: p1, apply: [‘b’,‘i’]})
  • new Edit({ dom: p2, apply: [‘b’,‘a’,‘br’]})

Theres something called input rules that does regexp on the input. I wouldn’t really consider this an “edit mode” sort of editor. You could certainly determine some special wrapping mechanic for your dom nodes if you wanted. But, Theres not really anything to stop you from using prosemirror’s mechanics to regulate what you want the whole thing to do, I just wouldn’t tell you it’s easy because, it wouldn’t be. The more customized you want, the more work you’re going to have for yourself.

As for your dom types like paragraph of type A and paragraph of type B. You can say what they’re allowed to have, to hair splitting detail. It uses a sort of regex style of content. So you can have many types of paragraphs that have very different inner contents, or the same paragraph that has lots of rules or very few rules, or both.

Requirement: no additional wrapping inside or ouside those tags in edit mode.

This simple code…

<p id="editor"></p>
...
...
import {schema} from "prosemirror-schema-basic"
import {EditorState} from "prosemirror-state"
import {EditorView} from "prosemirror-view"

let dom = document.getElementById('editor')
let state = EditorState.create({schema})
let view = new EditorView(dom, {state})

…appends a container to the ‘p’ element

<p id="editor">
  <div class="ProseMirror" contenteditable="true">
    <p>
      <br>
    </p>
  </div>
<p>

How can EditorView be initialized to do this:

<p id="editor" class="ProseMirror" contenteditable="true">
<p>

Mount removes the div container.

let view = new EditorView({mount: dom}, {state})

<p id="editor" class="ProseMirror" contenteditable="true">
    <p>
      <br>
    </p>
<p>

Like I said, there’s a learning curve.

@JCHollett Thank you very much for your input. As you said there is a learning curve and I still feel at the beginning. To help other beginners I started a github project with this proof of concept.

All of my requirements are met

  • multiple edit instances for p, h*, ul
    • multiple pm instance on one page works perfectly even tab jumps from one to the other instance!
  • no additional wrapping inside or ouside those tags in edit mode
    • works perfectly: mount dom and define custom schema
  • restrict inline tags for each instance. e.g. p -> b/i/br, ul -> b/i/a/li, h1 only edit or h1 -> b/i/br
    • works perfectly: define custom schemas
  • fine grade control over return: nothing happens, new li or br
    • I did succeed with br. li will be done later
  • air mode (pop up menu)
    • I did code a link pop up which was by far the hardest part. Not sure if this is the way to go but it works:

Some impressions

link popup

link edit popup

clone and point to dist/example/

Looks good. For the link popup, the tooltip example shows how I tend to do that.

@marijn a big thank to your inputs and great work! Without your fast and good responses it would be much harder to find a solution.

Your tooltip example helped a lot. Still there are many other things to solve like:

  • decide if cursor or selection is within a link mark
  • expand link from cursor position. First I searched for the link mark with the help of nodesBetween but there is no position property in mark instance.
  • open dialog from plugin, keyboard shortcut and menu icon
  • assign commands to dialog actions