diff --git a/static/js/compose_state.js b/static/js/compose_state.js index ecba205cae..052bc05cd6 100644 --- a/static/js/compose_state.js +++ b/static/js/compose_state.js @@ -31,7 +31,7 @@ export function composing() { return Boolean(message_type); } -function get_or_set(fieldname, keep_leading_whitespace) { +function get_or_set(fieldname, keep_leading_whitespace, no_trim) { // We can't hoist the assignment of '$elem' out of this lambda, // because the DOM element might not exist yet when get_or_set // is called. @@ -41,7 +41,12 @@ function get_or_set(fieldname, keep_leading_whitespace) { if (newval !== undefined) { $elem.val(newval); } - return keep_leading_whitespace ? oldval.trimEnd() : oldval.trim(); + if (no_trim) { + return oldval; + } else if (keep_leading_whitespace) { + return oldval.trimEnd(); + } + return oldval.trim(); }; } @@ -63,11 +68,18 @@ export const topic = get_or_set("stream_message_recipient_topic"); // of the indented syntax for multi-line code blocks. export const message_content = get_or_set("compose-textarea", true); +const untrimmed_message_content = get_or_set("compose-textarea", true, true); + +export function cursor_at_start_of_whitespace_in_compose() { + const cursor_position = $("#compose-textarea").caret(); + return message_content() === "" && cursor_position === 0; +} + export function focus_in_empty_compose() { // A user trying to press arrow keys in an empty compose is mostly // likely trying to navigate messages. This helper function - // decides whether the compose box is "empty" for this purpose. - if (!composing() || message_content() !== "") { + // decides whether the compose box is empty for this purpose. + if (!composing() || untrimmed_message_content() !== "") { return false; } diff --git a/static/js/hotkey.js b/static/js/hotkey.js index 7dbbf704a3..2fd0f50ef9 100644 --- a/static/js/hotkey.js +++ b/static/js/hotkey.js @@ -735,13 +735,11 @@ export function process_hotkey(e, hotkey) { } if ( - (event_name === "up_arrow" || - event_name === "down_arrow" || - event_name === "page_up" || - event_name === "page_down" || - event_name === "home" || - event_name === "end") && - compose_state.focus_in_empty_compose() + ((event_name === "down_arrow" || event_name === "page_down" || event_name === "end") && + compose_state.focus_in_empty_compose()) || + ((event_name === "up_arrow" || event_name === "page_up" || event_name === "home") && + (compose_state.focus_in_empty_compose() || + compose_state.cursor_at_start_of_whitespace_in_compose())) ) { compose_actions.cancel(); // don't return, as we still want it to be picked up by the code below