composebox_typeahead: Rewrite code for handling modifier+enter.

We've iterated on this code incorrectly something like 3 times now, so
it's worth rewriting it with a lot of comments in a way that makes
sense.

The main actual functional change here is that modified key + enter
now is consistently the opposite of enter (in terms of whether to
provide a newline or send the message) in all cases.

Fixes #6489.
This commit is contained in:
Tim Abbott 2017-09-29 17:09:17 -07:00
parent cdaa013416
commit 6c1c29408e
2 changed files with 67 additions and 7 deletions

View File

@ -603,6 +603,20 @@ global.people.add(deactivated_user);
event.target.id = 'some_non_existing_id'; event.target.id = 'some_non_existing_id';
$('form#send_message_form').keydown(event); $('form#send_message_form').keydown(event);
// Setup jquery functions used in new_message_content enter
// handler.
var range_length = 0;
$('#new_message_content').range = function () {
return {
length: range_length,
range: noop,
start: 0,
end: 0 + range_length,
};
};
$('#new_message_content').caret = noop;
event.keyCode = 13; event.keyCode = 13;
event.target.id = 'subject'; event.target.id = 'subject';
$('form#send_message_form').keydown(event); $('form#send_message_form').keydown(event);
@ -624,6 +638,12 @@ global.people.add(deactivated_user);
event.ctrlKey = false; event.ctrlKey = false;
event.altKey = true; event.altKey = true;
$('form#send_message_form').keydown(event); $('form#send_message_form').keydown(event);
// Cover case where there's a least one character there.
range_length = 2;
$('form#send_message_form').keydown(event);
event.altKey = false;
event.metaKey = true; event.metaKey = true;
$('form#send_message_form').keydown(event); $('form#send_message_form').keydown(event);
event.target.id = 'private_message_recipient'; event.target.id = 'private_message_recipient';

View File

@ -129,20 +129,60 @@ function handle_keydown(e) {
nextFocus = false; nextFocus = false;
} }
// Send the message on Ctrl/Cmd-Enter or if the user has configured enter to
// send and the Shift/Ctrl/Cmd/Alt keys are not pressed.
// Otherwise, make sure to insert a newline instead
if (e.target.id === "new_message_content" && code === 13) { if (e.target.id === "new_message_content" && code === 13) {
if ((!page_params.enter_sends && (e.metaKey || e.ctrlKey)) || var has_non_shift_modifier_key = e.ctrlKey || e.metaKey || e.altKey;
(page_params.enter_sends && !(e.shiftKey || e.ctrlKey || e.metaKey || e.altKey)) var has_modifier_key = e.shiftKey || has_non_shift_modifier_key;
) { var this_enter_sends;
if (page_params.enter_sends) {
// With the enter_sends setting, we should send
// the message unless the user was holding a
// modifier key.
this_enter_sends = !has_modifier_key;
} else {
// If enter_sends is not enabled, just hitting
// enter should add a newline, but with a modifier
// key held down, we should send.
this_enter_sends = has_modifier_key;
}
if (this_enter_sends) {
e.preventDefault(); e.preventDefault();
if ($("#compose-send-button").attr('disabled') !== "disabled") { if ($("#compose-send-button").attr('disabled') !== "disabled") {
$("#compose-send-button").attr('disabled', 'disabled'); $("#compose-send-button").attr('disabled', 'disabled');
compose.finish(); compose.finish();
} }
return;
} }
// Don't prevent default -- just let the enter key go in as usual.
// Since this enter doesn't send, we just want to do
// the browser's default behavior for the "enter" key.
// Letting the browser handle it works great if the
// key actually pressed was enter or shift-enter.
// But the default browser behavior for ctrl/alt/meta
// + enter is to do nothing, so we need to emulate
// the browser behavior for "enter" in those cases.
//
// We do this using caret and range from jquery-caret.
if (has_non_shift_modifier_key) {
var textarea = $("#new_message_content");
// To properly emulate browser "enter", if the
// user had selected something in the compose box,
// we need those characters to be cleared.
var range = textarea.range();
if (range.length > 0) {
textarea.range(range.start, range.end).range('');
}
// Now add the newline, remembering to resize the
// compose box if needed.
textarea.caret("\n");
compose_ui.autosize_textarea();
e.preventDefault();
return;
}
// Fall through to native browser behavior, otherwise.
} }
} }
} }