-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
I haven’t explored this space in a while, but I have a couple of examples that could be helpful. A Clojure library of mine [0] has a decent README with some background reading on how to use operational transform.
I also reimplemented it in a surprisingly tiny amount of OCaml [1] which was a fun way to learn that language :)
[0]: https://github.com/jahfer/othello
This single file shows the entire set of OT transformations (retain, insert, delete):
https://github.com/Operational-Transformation/ot.js/blob/mas...
and this is a good post outlining the basics of OT, from the creator of CodeMirror:
https://marijnhaverbeke.nl/blog/collaborative-editing-cm.htm...
nah, that’s not true at all. have a look at ‘rich-text’[1] which allows for transforms on metadata in a separate stream from the main content. it’s the same basic algo used for OT on plain text.
(i was the cto at a startup which used this to create a multi-user text editor with rich text support in 2015ish)
1: https://github.com/ottypes/rich-text
> Opaque State: [...] You can’t inspect your model represented by the CRDT without using the CRDT library to decode the blob, and you can’t just store the underlying model state because the CRDT needs its change history also. You’re left with an opaque blob of data in your database.
As someone who works on a CRDT library with opaque state [1], I agree that this is a big barrier to adoption. Features like partial loading, per-paragraph permissions, and accept/reject suggestions seem pretty easy to implement if each text char is just a row in your server's DB, but I would have trouble implementing them on top of e.g. Yjs.
For text editing, one idea is to separate the CRDT "positions" from the text itself, which you can then store as a map (position -> char) in your own data structures. I've made a simple (but inefficient) library along these lines [2] and would be interested in ideas for further development.
[1] Collabs - https://collabs.readthedocs.io
[2] position-strings - https://www.npmjs.com/package/position-strings
I agree. Yes, you can. Quill is the example here.
Actually, back in 2015 when we started prototyping CKEditor 5, we started with this approach as well. Our goal from the beginning was to combine real-time editing capabilities with an engine capable of storing and rendering complex rich-text structures (nested tables, complex nested lists, other rich widgets, etc.). We quickly realized that a linear structure is going to be a huge bottleneck. In the end, if you want to represent trees, storing them as a linear structure is counterproductive.
So, we went for a tree model. That got many things in the engine an order of magnitude harder (OT being one). But I choose to encapsulate this complexity in the model rather than make it leak to particular plugins.
In fact, from what I remember, https://github.com/quilljs/quill/issues/117 (e.g. https://github.com/quilljs/quill/issues/117#issuecomment-644...) is a good example of issues that we avoided.
I also talked to companies that built their platforms on top of Quill. One of them ended up gluing together countless Quill instances to power their editor and overcome the limitations of the linear data model but is now looking for a way to rebuild their editor from scratch due to the issues (performance, complexity, stability).
So, yes. You can implement a rich-text editor based on a linear model. But it has its immediate limitations that you need to take into consideration.
Related posts
-
Quill: Open-source, powerful rich text editor in JavaScript
-
I need help with creating simple text editor
-
Recommendations For A Better Blog UI
-
Are WYSIWYG text entry areas difficult to implement in web and mobile apps? Because I see Markdown so much instead.
-
What's rich text editor we should use nowadays ?