![]() But now we were able to use the same primitives to power our editor as well. Mind you, we needed most of this logic anyway, because we also needed it for our OT algorithm. When you’re typing in a cell, where do we insert the newly typed characters? How does that affect the content and the associated formatting? What should happen if you toggle formatting on a selection? What if you split a cell in the middle? All of this and more is implemented in the core logic in Rust. With the data model also comes code for interacting with it. In addition, the simplicity of only having a single offset for each annotation makes it easy for us to implement the Operational Transformation (OT) algorithm we use for collaboration. We intentionally did not choose a tree-like structure similar to HTML because formatting ranges can overlap, which would lead to complicated tree manipulation. For this post, we’ll focus on the TextCell:Īs you can see, it’s nothing but a list of annotations that define the type of formatting to apply and the offset from where it starts. So we settled on a data model that would be beneficial both for our collaboration features, as well as for the RTE that powers any of the rich text fields that we use inside cells. A notebook is a block-based editor comprised of different types of cells, ranging from text cells to images and graphs. Our product is a collaborative notebook editor. In this post, we’ll discuss the challenges we faced and how we tackled those. The downside? RTEs are notorious for their need to support complex user interactions, and now we would need to handle every interaction ourselves. If we could just implement the view directly in React, we could simplify our stack considerably and have full control over every aspect of it. We used Slate for the view, though as a result, it pulled in its own data model as well. A view that renders the state of said data model and that handles the user interactions. ![]() A data model and the core logic to operate on it.So we got to thinking - what if we just built our own Rich Text Editor (RTE)?įrom a very high-level perspective, a rich text editor is comprised of two components: We used to use Slate.js - a fine editor - but as we’re implementing our own rich text primitives for collaborative editing, we discovered the disconnect between our own primitives and Slate’s data model to be somewhat of a hindrance. We can render HTML in an editable div instead of a text area if we want to add a box where we can edit rich text.At Fiberplane, we recently encountered an interesting challenge: We were outgrowing the library we were using for our rich text editor. Now when we click on toggle red and toggle italic, we see the corresponding styles applied to the text we typed into it. The CSS just sets the width, border, padding, and overflow styles for the editable div. Likewise, we have the toggleItalic function to get the innerHTML from the editable div. Then we add a p element with color style set to red. Then we have the toggleRed function that gets the existing innerHTML from the editable div. We select all the elements we added with document.querySelector. We make the div editable with the contenteditable attribute set to true. editable bold.addEventListener('click', toggleRed) italic.addEventListener('click', toggleItalic) Then we can style it with the following CSS. we can use an editable div as we do with a text area but with HTML content.įor instance, we can write the following HTML: toggle red toggle italic However, we can make a div’s content editable with the contenteditable attribute. In this article, we’ll look at how to render HTML content inside a text area. Sometimes, we want to render HTML inside a text area.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |