mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 08:26:11 +00:00
compose: Always preserve cursor position post replacement in a textarea.
Refactored (moved) the code for preserving the cursor's initial logical position from `quote_and_reply()` in `compose_actions.js` which calls `replace_syntax()` directly into `replace_syntax()` in `compose_ui.js`. This ensures that anytime text in a textarea is replaced, the original cursor position is always restored. Earlier, this was needed to be done separately, and missing that would lead to bugs with the cursor unexpectedly jumping on replacement. Fixes: #23863.
This commit is contained in:
@@ -75,6 +75,11 @@ export function insert_syntax_and_focus(syntax, $textarea = $("#compose-textarea
|
||||
}
|
||||
|
||||
export function replace_syntax(old_syntax, new_syntax, $textarea = $("#compose-textarea")) {
|
||||
// The following couple lines are needed to later restore the initial
|
||||
// logical position of the cursor after the replacement
|
||||
const prev_caret = $textarea.caret();
|
||||
const replacement_offset = $textarea.val().indexOf(old_syntax);
|
||||
|
||||
// Replaces `old_syntax` with `new_syntax` text in the compose box. Due to
|
||||
// the way that JavaScript handles string replacements, if `old_syntax` is
|
||||
// a string it will only replace the first instance. If `old_syntax` is
|
||||
@@ -84,7 +89,25 @@ export function replace_syntax(old_syntax, new_syntax, $textarea = $("#compose-t
|
||||
// replace() function treating `$`s in new_syntax as special syntax. See
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Description
|
||||
// for details.
|
||||
|
||||
replace($textarea[0], old_syntax, () => new_syntax, "after-replacement");
|
||||
|
||||
// When replacing content in a textarea, we need to move the cursor
|
||||
// to preserve its logical position if and only if the content we
|
||||
// just added was before the current cursor position. If it was,
|
||||
// we need to move the cursor forward by the increase in the
|
||||
// length of the content after the replacement.
|
||||
if (prev_caret >= replacement_offset + old_syntax.length) {
|
||||
$textarea.caret(prev_caret + new_syntax.length - old_syntax.length);
|
||||
} else if (prev_caret > replacement_offset) {
|
||||
// In the rare case that our cursor was inside the
|
||||
// placeholder, we treat that as though the cursor was
|
||||
// just after the placeholder.
|
||||
$textarea.caret(replacement_offset + new_syntax.length + 1);
|
||||
} else {
|
||||
// Otherwise we simply restore it to it's original position
|
||||
$textarea.caret(prev_caret);
|
||||
}
|
||||
}
|
||||
|
||||
export function compute_placeholder_text(opts) {
|
||||
|
||||
Reference in New Issue
Block a user