My ProseMirror [1] project is in the same space (including using persistent data model detached from the DOM). It has a richer, tree-shaped document model and collaboration [2], but not quite as much programmerpower behind it since I'm a single OSS dev as opposed to a giant tech company.
Just wanted to take this opportunity to say thanks again for CodeMirror, and it's great to see the progress you've been making with ProseMirror.
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!
So cool to see one of my favorite products on here. Overleaf's rich text view is a total revolution for LaTeX editing and I've always wondered how it combined MathJax with an editor. Love this product.
Oh yes, I want to say thank you too! I just discovered CodeMirror, and it's wonderful. It was easy to make it to do just what I wanted, and it feels so snappy (both fast, and easily plugged together with other code). I'll definitely check out ProseMirror too.
As nacs said but in other words, CodeMirror is syntax colored and directed code editing (emacs), while ProseMirror is wysiwyg text editing (word).
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]
The model CodeMirror edits is flat text. It can apply styles (including variable fonts) that are a pure function of the text, and there are APIs to imperatively apply extra styling and even insert "widgets" (arbitrary DOM elements) and hooks to react to events. This lets you (ab)use CodeMirror for semi-WYSIWYG editing reasonably easily, but it works best when you strive to keep the rendering a function of the underlying text. E.g. Firepad abuses CodeMirror for WYSIWYG, which generally functions well, but after a couple years they're still debugging some problems with copy-paste. And I think they only pulled it off by maintaining a well-defined WYSIWYG data model underneath CodeMirror (they needed it for syncing).
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.
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).
Code is line-oriented and usually monospaced. Prose is not, and usually requires local layout (spacing, alignment and so on), embedded media (such as images) and variable typography.
ProseMirror is great. A few months back i was looking for a rich text editor for use in an isomorphic js webapp that uses react. I probably spent more time researching and testing out other libraries than i did getting prosemirror working in our app (and even ended up even contributing back some code in the process). Highly recommended, i think for most cases, prosemirror strikes a good balance between sensible defaults and easy integration.
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.
Well what I liked about Mobiledoc-kit[1] is that their demo was essentially an explanation of their document model. You changed things on the left, then saw the document model mutate in real time, and finally saw the rendered output.
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.
hi marjin! thanks again for all your work on prosemirror. the docs are quite thorough (and have gotten moreso in the past few months!), but a specific thing which i ended up needing to dive into the code for was something like setting up a custom menubar[1] with a menugroup.
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!
> I'm a single OSS dev as opposed to a giant tech company.
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.
FWIW, i always use Codemirror as an agument against DSL-specific, locked in components. While declarative React components are "reusable" they're only "reusable [within React]".
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.
I don't know if a lot of people set out thinking, "Oh I'm going to write a component, better do it in React [or Jquery]". They just use the tools they are familiar with to complete their own projects then long after the fact they decide to extract it out and open source it.
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.
That's right, but most people don't set out to write libraries from day one. They write an application, then extract useful functionality into a library and release that.
The users of the released library inherit whatever dependencies that weren't easily removeable.
It's worth clarifying that Isaac, the engineer behind Draft.js, also basically built the entire thing himself. He did it inside a large company of course, but it was his labour of love for a long, long time.
This is the type of cool stuff you get to work on at Facebook, come work with us :-)
After dropping thousands of Parse.com devs in the middle of the desert (albeit giving each a small bottle of water), you won't find many loving fans of the FB around here...
Maybe dramatic, but it did turn me into an anti-FB evangelist. If Parse did not align with FB's core there where other options than shutting it down (sell, split-off, turn it into a foundation, etc) but the fact that they just closed like that, disregarding its thousands of users, dropping tons of labor and cash, seems more of a signal of what exactly is going on behind the wall. My take is that services like Parse empower small shops/tiny startups and that is exactly what goes against FB's all-involving growth/power strategy. Maybe React will be like that too: so you want to develop FB (or Whatsapp) apps? You MUST use React...
Hi! Your project is amazing, as is CodeMirror. A few months ago, I was looking for an editor for a personal blog/notebook. I'm a programmer and I often want to write down ideas about programming languages, so I wanted an editor that would combine WYSIWYG with a syntax-highlighting code editor. After a lot of effort, I managed to embed CodeMirror into the CKEditor, with almost seamless editing without any modal windows. Since you're the author of both a code editor and a WYSIWYG editor, it would probably be easier for you to implement this kind of functionality, which would be really amazing for many use cases!
I have recently implemented ProseMirror for a client and added some functionality using the API and I can only say good things about this editor. It is everything I have been looking for in an embedded rich text editor for the web and I am thrilled to follow, and hope to be a part of, it's future development!
Do you want contributions? I've done a cursory check of the repo a couple times but my use thus far has been fairly low key and I haven't run into errors for bug reports and most of the stuff on your roadmap from last fall the sort of conceptual / organization work where outside contribution isn't particularly helpful.
The project is now at a point where contributions would make sense -- the API is documented, and the design somewhat stable. The area I'd most like help with is finding and resolving bugs -- strange browser behavior (contentEditable is a fountain of strange browser behavior) and issues on mobile. I'm still too busy moving the larger pieces forward to spend a lot of time testing.
Don't know about ProseMirror but I found the documentation for writing CodeMirror syntax highlighters to be very scarce.. The syntax files themselves look like huge procedural JS files with barely a comment :(
But apart from that, CM works like a charm out of the box, so thanks a ton for it :)
You should make a new post about that then, "ProseMirror Now accepting contributions!" and post it here on HN ;) Seems a lot of people here would support it.
> But you can save oh so much complexity by introducing a central point. I am, to be honest, extremely bewildered by Google's decision to use OT for their Google Docs—a centralized system.
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.
How does OT help make offline editing work in a way that a similar algorithm relying on a centralized system doesn't? Both are a form of Command pattern, both can store a buffer of changes to send to the server now or at a later time - OT just has more requirements and complexity in order to support peer-to-peer merging too, which Google Docs as far as we can tell doesn't actually use. I fail to see the difference vis-a-vis offline editing. (Not to mention that the very concept of "offline" requires there to be some central server from which you are disconnected).
[1]: https://prosemirror.net [2]: http://marijnhaverbeke.nl/blog/collaborative-editing.html