- RawEditorState can be reference from QuillEditorState. This interface details several methods that are available from the mixins added to the RawEditor class.
- These methods are defined in the inherited classes from Flutter. So this Class helps us keep in mind several useful methods such as:
- showToolbar()
- Triggers the mobile OS text selection toolbar.
- requestKeyboard()
- Triggers the mobile OS keyboard
- getSelectionOverlay()
**abstract RenderAbstractEditor**
- Base interface for editable render objects
- Defines which methods the RenderEditor must implement
- Seems to be defined for the sake of documenting the most important operations
Useful:
- selectWordAtPosition() selectLineAtPosition();
- getLocalRectForCaret() - Useful to enforce visibility of full caret at given position
- These methods are used to inform many parts of Quill that the controller state has changed
- This means we don't use ChangeNotifierProvider
- 15 listeners in total
- 12 for the buttons, stuff outside of Quill
- 1 for scroll arrows (if to show them)
- RawEditorState init and update listen _didChangeTextEditingValue → _onChangeTextEditingValue
- updateRemoteValueIfNeeded - When apps are sent into the background, the view ref is lost, when restoring the java code loses the state of the input.
- _showCaretOnScreen - Scrolls to show the carpet on screen
- start timer for blinking caret
- addPostFrameCallback - To be able to account for new lines of text when rendering the selection overlay
- _updateOrDisposeSelectionOverlayIfNeeded - Updates the mobile context menu. We can show here the text selection menu as well (ideally with middleware override).
EditorTextSelectionOverlay - An object that manages a pair of text selection handles.
Quill editors can have a Toolbar connected. The toolbar commands the controller which in turn commands the Document which commands the Renderer.
The toolbar can be customized to show all or part of the editing controls/buttons.
The Toolbar offers callbacks for reacting to adding images or videos.
For our own custom embeds we don't have to define extra callback here on the Toolbar context. We can host the logic in our own custom embeds (they are part of our own codebase).
`EditorTextSelectionGestureDetectorBuilderDelegate` - Signatures for the methods that the EditableText (QuillEditor) must define to be able to run gesture detector
- RawEditorState can be referenced from QuillEditorState.
- EditorState interface details several methods that are available from the mixins added to the RawEditor class.
with `AutomaticKeepAliveClientMixin<RawEditor>`
- Indicates that the subtree through which this notification bubbles must be kept alive even if it would normally be discarded as an optimization.
- For example, a focused text field might fire this notification to indicate that it should not be disposed even if the user scrolls the field off screen.
WidgetsBindingObserver
- Notifies when new routes are pushed or poped such that the app can react accordingly (for ex if the app exits)
TickerProviderStateMixin<RawEditor>
- Synchronizes the animations of the widget with all other animations so that they can all complete before the new frame is to be rendered
RawEditorStateTextInputClientMixin
- Connector that links the editor to the Mobile keyboard
`RawEditorStateSelectionDelegateMixin`
- A mixin that controls text insertion operations. It is a delegate for Flutter's TextSelection.
- it can override the setter for `textEditingValue()`
- It intercepts copy paste ops from the system, it commands the QuillEditor controller to run the necessary changes.
- In other words, that's how Quill knows how to react to text editing ops coming from the system (user input).
`_getOffsetToRevealCaret()`
- Finds the closest scroll offset to the current scroll offset that fully reveals the given caret rect.
- If the given rect's main axis extent is too large to be fully revealed in `renderEditable`, it will be centered along the main axis.
- build()
- If no delta document is available an empty one will be created
- If expanded true it builds an _Editor wrapped with Semantics and CompositedTransformTarget
- Semantics is used for screen readers
- CompositedTransformTarget - Hooks the custom widget into the mechanics of layout rendering and calculation of dimensions (Flutter).
- Why CompositedTransformTarget? - Because Quill uses a custom renderer to render the document (for performance reasons)
- If not expanded (meaning scrollable) it wraps the _editor with BaselineProxy QuillSingleChildScrollView and CompositedTransformTarget
Since [SingleChildScrollView] does not implement `computeDistanceToActualBaseline` it prevents the editor from providing its baseline metrics.
To address this issue we wrap the scroll view with [BaselineProxy] which mimics the editor's baseline.
This implies that the first line has no styles applied to it.
Why is computeDistanceToActualBaseline needed?
If my intuition is right this is needed to scroll the page the right amount to offset the scroll to match the off screen selected text line when the carpet is moved.
It computes the distance from top to the baseline of the first text. First text out of first editable text. I'll explain bellow, there are more lines of text in a Quill doc.
- Nested in the _Editor we have the _buildChildren(_doc, context)
This method loops trough the delta breaks it into text lines and text blocks and renders the corresponding children
From here on the works of rendering the text starts
- Finally the whole thing is wrapped in QuillStyles, Actions, Focus, QuillKeyboardListener and returned for the build()
- Actions are callbacks registered to respond on Intents (Flutter alternative to callbacks)
After all these layers: Gesture detectors, mixins, scrolls, actions, etc we finally arrive at the layer that handles the edit operations.
_Render creates and updates the RenderEditor which is basically the custom RenderBox that handles the coordination between multiple line models.
For example the RenderEditor knows how to coordinate multiple lines to draw a selection of text between them. It commands their widgets to render the correct selections.
This is where we need to add our own code for rendering multiple highlights. It queries and coordinates both the models and the render boxes.
MultiChildRenderObjectWidget takes the duty of rendering the line and block widgets that were created by the _buildChildren()
Very similar to `SingleChildView` but with a `ViewportBuilder` argument instead of a `Widget`→ Meaning it can scroll over the CompositedTransformTarget instead of Widgets
A `ScrollController` serves several purposes.
It can be used to control the initial scroll position (see `ScrollController.initialScrollOffset`).
It can be used to control whether the scroll view should automatically save and restore its scroll position in the `PageStorage` (see `ScrollController.keepScrollOffset`).
It can be used to read the current scroll position (see `ScrollController.offset`), or change it (see `ScrollController.animateTo`)
showOnScreen() → The most important method here. It is invoked in several scenarios to expose the selected text on screen of off-page.
Now since our ArticlePage uses several stacked expanded editors (due to post topics) we don't use at all the scrolling behaviour.
If we wanted to use the scroll behaviour from Quill that means we would have to make the entire post topic together with the article topic.
It means one could copy paste the post topics to the bottom of the article which makes absolutely no sense. So therefore we have to handle this part ourselves.
And since the Article and topics are scrolled together by a greater scroll controller we are force to render the article editor as well in the expanded mode.
That make our situation a bit harder because we might have to redo some of the work needed to bring the selected text back into view when moving the carpet.
This is a luxury item for the moment, we don't care of this feature missing in the MVP. So no panic if we don't use the QuillEditorScroll.
`_Editor`
- A container with lifecycle calls create and update for RenderBoxes (RenderEditor)
`RenderBaselineProxy` - Renders the scrollable input
`RenderEmbedProxy` - Renders embeds
`RichTextProxy` - rich text
`RenderParagraphProxy` - RenderProxyBox - Mimics it's children
`getBoxesForSelection()` - This code is used from Flutter
**models/quill_delta.dart**
- Container various utils for handling delta text
- insert
- skip
- retain
- slice - This might be super useful for splitting docs
- concat
- diff
- delta.insert('\n' - used to add new character → Could be used to split our deltas
- DeltaIterator(document)..skip(index) - Skips [length] characters in source delta.
- Delta()..retain - Retain [count] of characters from current position.
- _trimNewLine() - Removes trailing '\n'
**text_selection.dart**
`EditorTextSelectionOverlay`
- Represents the selection overlay object (the highlight)
- It also renders the mobile actions menu and handles. This is from the system.
**document.dart**
The Document contains the Delta which contains all the operations. Inside operations we can find attributes. The attributes are useful for examining the text.
- These methods are extremely useful
- insert → Can insert embeddable, Can replace selected text
- delete
- replace
- format
- undo, hasUndo
- redo, hasRedo
- toPlainText
- isEmpty
- toDelta
- setCustomRules -→ Could be extremely useful because we can edit the text editor each time something outstanding happens
**/rules**
- Seems to contain business logic for handling operations and delta modifications
- PreserveLineStyleOnSplitRule - Preserves the style to the split line
**node.dart**
An abstract node in a document tree.
Represents a segment of a Quill document with specified offset and length. The offset property is relative to parent.
See also documentOffset which provides absolute offset of this node within the document.