Fix caret position after multi line paste #870
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR is a draft with the intent to open a discussion about how best to handle pasting multi-line content. The code changes are early steps to addressing this issue: #828. This comment in particular contains details about the multi-line case: #828 (comment).
Related gutenberg PR: WordPress/gutenberg#14974
Note
This PR should not be merged, as the changes in #789 and WordPress/gutenberg#14662 will conflict.
Currently, when multi-line content is pasted into a paragraph block, the content is split into multiple blocks, splitting the current block if necessary (if the caret position is somewhere in the middle of the original block's text). After the paste event ends, the first pasted block is focused, with the caret at the start of that block's text.
These changes expose a
selectBlock
method from theBlockHolder
object, and make it available to the RichText component. This is sufficient for the RichText component receiving the paste event to select the last pasted block after inserting multiple blocks. However, this is not sufficient to ensure the caret is in the correct position on selected block.In order to ensure the caret is in the correct position after paste, it may be possible to expose a method to the RichText component to manipulate the selection in a sibling block, or alternatively, pass selection information to a block at creation. Neither of these approaches feel particularly elegant. In both of these cases, I suspect a race condition will exist, as the underlying native instantiation of sibling blocks will only occur asynchronously, after the paste method has terminated. This could theoretically be resolved via a callback, but I'd like to explore some ideas to see if a better approach can be found.
One concern with implementing the required behavior is that
onSplit
is used by bothonPaste
andonEnter
. WhenonEnter
is called, it creates a new "sibling" block containing the text following the caret. In this case, the expected caret position after the event is at the start of the new block. This is currently satisfied by setting the selection to 0 in native code when the view is instantiated (e.g. in Android, this occurs via the methodforceCaretAtStartOnTakeFocus
).With the refactor and "porting" of
BlockHolder
andBlockManager
to Gutenberg asBlockListBlock
andBlockList
respectively, I wonder if a solution can be implemented that could resolve this issue across mobile and web platforms.How has this been tested?
This has been tested using the steps here:
#828 (comment)
Screenshots
Types of changes
This is a partial bug fix, but currently only resolves a part of the original issue. It serves as an incremental improvement. This is not intended to be merged.