📚 Add more info about text editor v2

This commit is contained in:
Aitor Moreno
2025-11-03 11:37:07 +01:00
parent 4ed49cdc5d
commit e05b4eb51b

View File

@@ -37,7 +37,7 @@ This command is going to search for the file located in `frontend/src/app/main/u
## How it works?
The text editor divides the content in three elements: `root`, `paragraph` and `inline`. An `inline` in terms of content is a styled element that it is displayed in a line inside a block and an `inline` only can have one child (a Text node). A `paragraph` is a **block** element that can contain multiple `inline`s (**inline** elements).
The text editor divides the content in three elements: `root`, `paragraph` and `textSpan`. An `textSpan` in terms of content is a styled element that it is displayed in a line inside a block and an `textSpan` only can have one child (a Text node). A `paragraph` is a **block** element that can contain multiple `textSpan`s (**textSpan** elements).
```html
<div data-itype="root">
@@ -53,10 +53,10 @@ This way we only need to deal with a structure like this, where circular nodes a
```mermaid
flowchart TB
root((root)) --> paragraph((paragraph))
paragraph --> inline_1((inline))
paragraph --> inline_2((inline))
inline_1 --> text_1[Hello, ]
inline_2 --> text_2[World!]
paragraph --> text_span_1((textSpan))
paragraph --> text_span_2((textSpan))
text_span_1 --> text_1[Hello, ]
text_span_2 --> text_2[World!]
```
This is compatible with the way Penpot stores text content.
@@ -68,6 +68,26 @@ flowchart TB
paragraph --> text((text))
```
## How the TextEditor works?
```mermaid
flowchart TB
TextEditor -->|handles `selectionchange` events| SelectionController
TextEditor -->|handles how the editor dispatches changes| ChangeController
```
The `TextEditor` keeps a reference to a series of elements, one of them is a `contenteditable` element that keeps the sub-elements explained before (root, paragraphs and textspans).
`SelectionController` listens to the `document` event called `selectionchange`. This event is called everytime the focus/selection of the browser changes.
`ChangeController` is called by the `TextEditor` instance everytime a change is performed on the content of the `contenteditable` element.
### Events
- `change`: This event is dispatched every time a change is made in the editor. All changes are debounced to prevent dispatching too many change events. This event is also dispatched when there are pending change events and the user blurs the textarea element.
- `stylechange`: This event is dispatched every time the `currentStyle` changes. This normally happens when the user changes the caret position or the selection and the `currentStyle` is re-computed.
## How the code is organized?
- `editor`: contains everything related to the TextEditor. Where `TextEditor.js` is the main file where all the basic code of the editor is handled. This has been designed so that in the future, when the Web Components API is more stable and has features such as handling selection events within shadow roots we will be able to update this class with little effort.