[1]: https://prosemirror.net [2]: http://marijnhaverbeke.nl/blog/collaborative-editing.html
[1]: https://prosemirror.net [2]: http://marijnhaverbeke.nl/blog/collaborative-editing.html
We use CM at Overleaf[1], and it's been fantastic. To make it easier for non-LaTeX users to collaborate on LaTeX documents, we built our own rich text editor on top of it[2], which is still in beta. Still got a long way to go!
But, then again, shouldn't a single editor be able to handle those two usage-domains? (As this would mean the editor would be more powerful in terms of extensibility).
ProseMirror's model is structured. It's a nesting of elements strictly conforming to a configurable schema (by default close in spirit to Markdown - paragraphs/lists, emphasis, links, etc). Note that it's not "flat WYSIWYG" where each character/line has a style; a sub-list is actually inside the parent list, not just a bullet which happens to have higher indentation.
CodeMirror was started in early 2007. [1] ProseMirror is newer, announced July 7 2015 [2]. You've probably been using CodeMirror but didn't even realize it -- it's ubiquitous!
>CodeMirror is an open-source project shared under an MIT license. It is the editor used in the dev tools for both Firefox and Chrome, Light Table, Adobe Brackets, Bitbucket, and many other projects [3].
Check out the CodeMirror JavaScript, HTML and Markup code folding demo -- who could say no to that? [4]
[1] https://en.wikipedia.org/wiki/CodeMirror
[2] http://marijnhaverbeke.nl/blog/prosemirror.html
What was so cool recently was that a group of 7th/8th graders[1] used us to write their 300-page engineering notebook!! Just amazing :)
[1] https://www.overleaf.com/blog/289-the-nano-ninjas-building-r...
Where it falls down is mostly in documentation, which is 100% understandable, since it was crowdfunded(!), but the code is very legible and amenable to most kinds of webapps.
Where i suspect draft.js probably shines is having tighter client/data boundaries and code that natively expects to be rendered isomorphically, so calls to window/document are probably more tightly managed given that the whole view layer uses react and likely expects to be rendered on the server.
That said, ProseMirror has a 100% fantastic "give me the current ast rendered as markdown" which, in my case at least, was the thing i wanted the most and that ProseMirror supplied handily. Draft.js will have you roll your own[1], but at least the draft.js api is fairly friendly.
There's obviously more than enough room for both projects, but i think that for react based projects, draft.js will feel like a more natural fit even if it will take more effort in the short term until more functionality builds up around it.
[1]: https://github.com/facebook/draft-js/blob/06891490069d3ccfb8...
Also, the very first thing in their documentation is an explanation of how to write a 'card' for embedded input, which is what is used to embed images in the demo.
It was an ah-ha! moment for me because most editor documentation begins by telling you how they parse ranges, and showing you how you can use regex to back-check to document and change it to your own elements, etc. That's just too deep into the internals for me to get an idea of what's going on.
The docs back then (and even now) do this thing where they get rapidly tautological and have you hop around between type definitions but don't, for instance, show you what the default `menuBar`'s content value is, in terms of a MenuGroup so it's not readily obvious how to customize my own without reading the source.
So reading the docs, while i can certainly find out what things are and how they connect, i don't have a good sense of what decisions prosemirror made for me (or how it made them) so that i can intentionally customize or integrate in a non-backwards way. If the code weren't so legible, this would be a massive problem, but it's the sort of in-depth documentation that needs somebody working strictly on documentation in that way that kaplan-moss talks about[2]. I totally get that prosemirror is early days and integrating it has been a good experience, but that's the sort of documentation pain-point i was referring to. Thanks again!
[1]: http://prosemirror.net/ref.html#menu/menubar [2]: https://jacobian.org/writing/great-documentation/
Yes, but you are Marijn Haverbeke and they are not. I have more faith in your ability to make good decisions than I have in any giant tech company, TBH.
Imperative components with APIs is where real reusability exists. Case in point: React can consume them but cannot create them for external consumption.
EDIT: I hate to make this reply self-serving, but this is exactly why domvm [1] now exists. It promotes imperative components with declarative OR imperative view/subview composition. It slots firmly in between Mithril and pure-vdom frameworks, removing structural enforcement and avoiding promotion of a specific MV* paradigm. It's among the most performant vdom implementations to boot.
At least, that's how I operate.
If your component is React all the way down, it will be anything but trivial to extract it and could amount to a full rewrite. In reality this is true for whichever view layer you end up using (domvm included). The difference comes down to the structural flexibility the view layer affords you, speed and the weight it adds to your app code. domvm is 9k min for the view core or 13k min w/mutation observers, isomorphism and router.
In some sense, a jQuery component is much more reusable but slower than any view layer and the most ad-hoc. While there's still a dependency, there is not a jQuery-imposed structural dependency since most of what you're doing with jQuery is manipulating the DOM with some sugar.
When you write a library, you need to think very carefully about the deps you bring because you'll be imposing it to all your users.
The users of the released library inherit whatever dependencies that weren't easily removeable.
This is the type of cool stuff you get to work on at Facebook, come work with us :-)
We'll see how this plays out.
But apart from that, CM works like a charm out of the box, so thanks a ton for it :)
Could a reason be that Google Docs allows for offline editing (if you install the Chrome extension), making it easier to save all these changes at once when an internet connection returns? You mention later that OT doesn't help when trying to merge conflicting edits (in which case Google Docs will spawn a "<collaborator>'s conflicting copy of <document name>", IIRC). However, if this level of conflicting desynchronisation is rare, and if OT makes it easy to push large changes after editing the document offline for a while, they might have decided it was worth it.