mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	compose: Move keydown and keyup from compose.js to compose_ui.js.
This commit moves the handle_keydown and handle_keydown functions of compose.js to compose_ui.js. Part of splitting compose.js.
This commit is contained in:
		@@ -111,188 +111,6 @@ function initialize_handlers({override}) {
 | 
			
		||||
    compose.initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test_ui("right-to-left", () => {
 | 
			
		||||
    const textarea = $("#compose-textarea");
 | 
			
		||||
 | 
			
		||||
    const event = {
 | 
			
		||||
        key: "A",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), false);
 | 
			
		||||
 | 
			
		||||
    textarea.val("```quote\nمرحبا");
 | 
			
		||||
    compose.handle_keyup(event, $("#compose-textarea"));
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), true);
 | 
			
		||||
 | 
			
		||||
    textarea.val("```quote foo");
 | 
			
		||||
    compose.handle_keyup(event, textarea);
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), false);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test_ui("markdown_shortcuts", ({override}) => {
 | 
			
		||||
    let queryCommandEnabled = true;
 | 
			
		||||
    const event = {
 | 
			
		||||
        key: "b",
 | 
			
		||||
        target: {
 | 
			
		||||
            id: "compose-textarea",
 | 
			
		||||
        },
 | 
			
		||||
        stopPropagation: noop,
 | 
			
		||||
        preventDefault: noop,
 | 
			
		||||
    };
 | 
			
		||||
    let input_text = "";
 | 
			
		||||
    let range_start = 0;
 | 
			
		||||
    let range_length = 0;
 | 
			
		||||
    let compose_value = $("#compose_textarea").val();
 | 
			
		||||
    let selected_word = "";
 | 
			
		||||
 | 
			
		||||
    override(document, "queryCommandEnabled", () => queryCommandEnabled);
 | 
			
		||||
 | 
			
		||||
    override(document, "execCommand", (cmd, bool, markdown) => {
 | 
			
		||||
        const compose_textarea = $("#compose-textarea");
 | 
			
		||||
        const value = compose_textarea.val();
 | 
			
		||||
        $("#compose-textarea").val(
 | 
			
		||||
            value.slice(0, compose_textarea.range().start) +
 | 
			
		||||
                markdown +
 | 
			
		||||
                value.slice(compose_textarea.range().end),
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#compose-textarea")[0] = {};
 | 
			
		||||
    $("#compose-textarea").range = () => ({
 | 
			
		||||
        start: range_start,
 | 
			
		||||
        end: range_start + range_length,
 | 
			
		||||
        length: range_length,
 | 
			
		||||
        range: noop,
 | 
			
		||||
        text: $("#compose-textarea")
 | 
			
		||||
            .val()
 | 
			
		||||
            .slice(range_start, range_length + range_start),
 | 
			
		||||
    });
 | 
			
		||||
    $("#compose-textarea").caret = noop;
 | 
			
		||||
 | 
			
		||||
    function test_i_typed(isCtrl, isCmd) {
 | 
			
		||||
        // Test 'i' is typed correctly.
 | 
			
		||||
        $("#compose-textarea").val("i");
 | 
			
		||||
        event.key = "i";
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("i", $("#compose-textarea").val());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function all_markdown_test(isCtrl, isCmd) {
 | 
			
		||||
        input_text = "Any text.";
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        compose_value = $("#compose-textarea").val();
 | 
			
		||||
        // Select "text" word in compose box.
 | 
			
		||||
        selected_word = "text";
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
 | 
			
		||||
        // Test bold:
 | 
			
		||||
        // Mac env = Cmd+b
 | 
			
		||||
        // Windows/Linux = Ctrl+b
 | 
			
		||||
        event.key = "b";
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any **text**.", $("#compose-textarea").val());
 | 
			
		||||
        // Test if no text is selected.
 | 
			
		||||
        range_start = 0;
 | 
			
		||||
        // Change cursor to first position.
 | 
			
		||||
        range_length = 0;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("****Any **text**.", $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        // Test italic:
 | 
			
		||||
        // Mac = Cmd+I
 | 
			
		||||
        // Windows/Linux = Ctrl+I
 | 
			
		||||
        // We use event.key = "I" to emulate user using Caps Lock key.
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.key = "I";
 | 
			
		||||
        event.shiftKey = false;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any *text*.", $("#compose-textarea").val());
 | 
			
		||||
        // Test if no text is selected.
 | 
			
		||||
        range_length = 0;
 | 
			
		||||
        // Change cursor to first position.
 | 
			
		||||
        range_start = 0;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("**Any *text*.", $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        // Test link insertion:
 | 
			
		||||
        // Mac = Cmd+Shift+L
 | 
			
		||||
        // Windows/Linux = Ctrl+Shift+L
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.key = "l";
 | 
			
		||||
        event.shiftKey = true;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any [text](url).", $("#compose-textarea").val());
 | 
			
		||||
        // Test if exec command is not enabled in browser.
 | 
			
		||||
        queryCommandEnabled = false;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This function cross tests the Cmd/Ctrl + Markdown shortcuts in
 | 
			
		||||
    // Mac and Linux/Windows environments.  So in short, this tests
 | 
			
		||||
    // that e.g. Cmd+B should be ignored on Linux/Windows and Ctrl+B
 | 
			
		||||
    // should be ignored on Mac.
 | 
			
		||||
    function os_specific_markdown_test(isCtrl, isCmd) {
 | 
			
		||||
        input_text = "Any text.";
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        compose_value = $("#compose-textarea").val();
 | 
			
		||||
        selected_word = "text";
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
 | 
			
		||||
        event.key = "b";
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        event.key = "i";
 | 
			
		||||
        event.shiftKey = false;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        event.key = "l";
 | 
			
		||||
        event.shiftKey = true;
 | 
			
		||||
        compose.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // These keyboard shortcuts differ as to what key one should use
 | 
			
		||||
    // on MacOS vs. other platforms: Cmd (Mac) vs. Ctrl (non-Mac).
 | 
			
		||||
 | 
			
		||||
    // Default (Linux/Windows) userAgent tests:
 | 
			
		||||
    navigator.platform = "";
 | 
			
		||||
 | 
			
		||||
    test_i_typed(false, false);
 | 
			
		||||
    // Check all the Ctrl + Markdown shortcuts work correctly
 | 
			
		||||
    all_markdown_test(true, false);
 | 
			
		||||
    // The Cmd + Markdown shortcuts should do nothing on Linux/Windows
 | 
			
		||||
    os_specific_markdown_test(false, true);
 | 
			
		||||
 | 
			
		||||
    // Setting following platform to test in mac env
 | 
			
		||||
    navigator.platform = "MacIntel";
 | 
			
		||||
 | 
			
		||||
    // Mac userAgent tests:
 | 
			
		||||
    test_i_typed(false, false);
 | 
			
		||||
    // The Ctrl + Markdown shortcuts should do nothing on mac
 | 
			
		||||
    os_specific_markdown_test(true, false);
 | 
			
		||||
    // Check all the Cmd + Markdown shortcuts work correctly
 | 
			
		||||
    all_markdown_test(false, true);
 | 
			
		||||
 | 
			
		||||
    // Reset userAgent
 | 
			
		||||
    navigator.userAgent = "";
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test_ui("send_message_success", ({override}) => {
 | 
			
		||||
    override(drafts, "delete_active_draft", () => {});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,11 +9,14 @@ const {mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
 | 
			
		||||
const {run_test} = require("../zjsunit/test");
 | 
			
		||||
const $ = require("../zjsunit/zjquery");
 | 
			
		||||
 | 
			
		||||
const noop = () => {};
 | 
			
		||||
 | 
			
		||||
set_global("document", {
 | 
			
		||||
    execCommand() {
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
set_global("navigator", {});
 | 
			
		||||
 | 
			
		||||
mock_esm("../../static/js/message_lists", {
 | 
			
		||||
    current: {},
 | 
			
		||||
@@ -456,3 +459,185 @@ run_test("test_compose_height_changes", ({override}) => {
 | 
			
		||||
    assert.ok(!compose_ui.is_full_size());
 | 
			
		||||
    assert.ok(!compose_box_top_set);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test("markdown_shortcuts", ({override}) => {
 | 
			
		||||
    let queryCommandEnabled = true;
 | 
			
		||||
    const event = {
 | 
			
		||||
        key: "b",
 | 
			
		||||
        target: {
 | 
			
		||||
            id: "compose-textarea",
 | 
			
		||||
        },
 | 
			
		||||
        stopPropagation: noop,
 | 
			
		||||
        preventDefault: noop,
 | 
			
		||||
    };
 | 
			
		||||
    let input_text = "";
 | 
			
		||||
    let range_start = 0;
 | 
			
		||||
    let range_length = 0;
 | 
			
		||||
    let compose_value = $("#compose_textarea").val();
 | 
			
		||||
    let selected_word = "";
 | 
			
		||||
 | 
			
		||||
    override(document, "queryCommandEnabled", () => queryCommandEnabled);
 | 
			
		||||
 | 
			
		||||
    override(document, "execCommand", (cmd, bool, markdown) => {
 | 
			
		||||
        const compose_textarea = $("#compose-textarea");
 | 
			
		||||
        const value = compose_textarea.val();
 | 
			
		||||
        $("#compose-textarea").val(
 | 
			
		||||
            value.slice(0, compose_textarea.range().start) +
 | 
			
		||||
                markdown +
 | 
			
		||||
                value.slice(compose_textarea.range().end),
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#compose-textarea")[0] = {};
 | 
			
		||||
    $("#compose-textarea").range = () => ({
 | 
			
		||||
        start: range_start,
 | 
			
		||||
        end: range_start + range_length,
 | 
			
		||||
        length: range_length,
 | 
			
		||||
        range: noop,
 | 
			
		||||
        text: $("#compose-textarea")
 | 
			
		||||
            .val()
 | 
			
		||||
            .slice(range_start, range_length + range_start),
 | 
			
		||||
    });
 | 
			
		||||
    $("#compose-textarea").caret = noop;
 | 
			
		||||
 | 
			
		||||
    function test_i_typed(isCtrl, isCmd) {
 | 
			
		||||
        // Test 'i' is typed correctly.
 | 
			
		||||
        $("#compose-textarea").val("i");
 | 
			
		||||
        event.key = "i";
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("i", $("#compose-textarea").val());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function all_markdown_test(isCtrl, isCmd) {
 | 
			
		||||
        input_text = "Any text.";
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        compose_value = $("#compose-textarea").val();
 | 
			
		||||
        // Select "text" word in compose box.
 | 
			
		||||
        selected_word = "text";
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
 | 
			
		||||
        // Test bold:
 | 
			
		||||
        // Mac env = Cmd+b
 | 
			
		||||
        // Windows/Linux = Ctrl+b
 | 
			
		||||
        event.key = "b";
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any **text**.", $("#compose-textarea").val());
 | 
			
		||||
        // Test if no text is selected.
 | 
			
		||||
        range_start = 0;
 | 
			
		||||
        // Change cursor to first position.
 | 
			
		||||
        range_length = 0;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("****Any **text**.", $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        // Test italic:
 | 
			
		||||
        // Mac = Cmd+I
 | 
			
		||||
        // Windows/Linux = Ctrl+I
 | 
			
		||||
        // We use event.key = "I" to emulate user using Caps Lock key.
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.key = "I";
 | 
			
		||||
        event.shiftKey = false;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any *text*.", $("#compose-textarea").val());
 | 
			
		||||
        // Test if no text is selected.
 | 
			
		||||
        range_length = 0;
 | 
			
		||||
        // Change cursor to first position.
 | 
			
		||||
        range_start = 0;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("**Any *text*.", $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        // Test link insertion:
 | 
			
		||||
        // Mac = Cmd+Shift+L
 | 
			
		||||
        // Windows/Linux = Ctrl+Shift+L
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.key = "l";
 | 
			
		||||
        event.shiftKey = true;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal("Any [text](url).", $("#compose-textarea").val());
 | 
			
		||||
        // Test if exec command is not enabled in browser.
 | 
			
		||||
        queryCommandEnabled = false;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This function cross tests the Cmd/Ctrl + Markdown shortcuts in
 | 
			
		||||
    // Mac and Linux/Windows environments.  So in short, this tests
 | 
			
		||||
    // that e.g. Cmd+B should be ignored on Linux/Windows and Ctrl+B
 | 
			
		||||
    // should be ignored on Mac.
 | 
			
		||||
    function os_specific_markdown_test(isCtrl, isCmd) {
 | 
			
		||||
        input_text = "Any text.";
 | 
			
		||||
        $("#compose-textarea").val(input_text);
 | 
			
		||||
        compose_value = $("#compose-textarea").val();
 | 
			
		||||
        selected_word = "text";
 | 
			
		||||
        range_start = compose_value.search(selected_word);
 | 
			
		||||
        range_length = selected_word.length;
 | 
			
		||||
        event.metaKey = isCmd;
 | 
			
		||||
        event.ctrlKey = isCtrl;
 | 
			
		||||
 | 
			
		||||
        event.key = "b";
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        event.key = "i";
 | 
			
		||||
        event.shiftKey = false;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
 | 
			
		||||
        event.key = "l";
 | 
			
		||||
        event.shiftKey = true;
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea"));
 | 
			
		||||
        assert.equal(input_text, $("#compose-textarea").val());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // These keyboard shortcuts differ as to what key one should use
 | 
			
		||||
    // on MacOS vs. other platforms: Cmd (Mac) vs. Ctrl (non-Mac).
 | 
			
		||||
 | 
			
		||||
    // Default (Linux/Windows) userAgent tests:
 | 
			
		||||
    navigator.platform = "";
 | 
			
		||||
 | 
			
		||||
    test_i_typed(false, false);
 | 
			
		||||
    // Check all the Ctrl + Markdown shortcuts work correctly
 | 
			
		||||
    all_markdown_test(true, false);
 | 
			
		||||
    // The Cmd + Markdown shortcuts should do nothing on Linux/Windows
 | 
			
		||||
    os_specific_markdown_test(false, true);
 | 
			
		||||
 | 
			
		||||
    // Setting following platform to test in mac env
 | 
			
		||||
    navigator.platform = "MacIntel";
 | 
			
		||||
 | 
			
		||||
    // Mac userAgent tests:
 | 
			
		||||
    test_i_typed(false, false);
 | 
			
		||||
    // The Ctrl + Markdown shortcuts should do nothing on mac
 | 
			
		||||
    os_specific_markdown_test(true, false);
 | 
			
		||||
    // Check all the Cmd + Markdown shortcuts work correctly
 | 
			
		||||
    all_markdown_test(false, true);
 | 
			
		||||
 | 
			
		||||
    // Reset userAgent
 | 
			
		||||
    navigator.userAgent = "";
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
run_test("right-to-left", () => {
 | 
			
		||||
    const textarea = $("#compose-textarea");
 | 
			
		||||
 | 
			
		||||
    const event = {
 | 
			
		||||
        key: "A",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), false);
 | 
			
		||||
 | 
			
		||||
    textarea.val("```quote\nمرحبا");
 | 
			
		||||
    compose_ui.handle_keyup(event, $("#compose-textarea"));
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), true);
 | 
			
		||||
 | 
			
		||||
    textarea.val("```quote foo");
 | 
			
		||||
    compose_ui.handle_keyup(event, textarea);
 | 
			
		||||
 | 
			
		||||
    assert.equal(textarea.hasClass("rtl"), false);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ import render_compose_private_stream_alert from "../templates/compose_private_st
 | 
			
		||||
 | 
			
		||||
import * as blueslip from "./blueslip";
 | 
			
		||||
import * as channel from "./channel";
 | 
			
		||||
import * as common from "./common";
 | 
			
		||||
import * as compose_actions from "./compose_actions";
 | 
			
		||||
import * as compose_error from "./compose_error";
 | 
			
		||||
import * as compose_fade from "./compose_fade";
 | 
			
		||||
@@ -28,7 +27,6 @@ import * as reminder from "./reminder";
 | 
			
		||||
import * as rendered_markdown from "./rendered_markdown";
 | 
			
		||||
import * as resize from "./resize";
 | 
			
		||||
import * as rows from "./rows";
 | 
			
		||||
import * as rtl from "./rtl";
 | 
			
		||||
import * as sent_messages from "./sent_messages";
 | 
			
		||||
import * as server_events from "./server_events";
 | 
			
		||||
import * as settings_data from "./settings_data";
 | 
			
		||||
@@ -337,77 +335,6 @@ export function update_email(user_id, new_email) {
 | 
			
		||||
    compose_state.private_message_recipient(reply_to);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handle_keydown(event, textarea) {
 | 
			
		||||
    // The event.key property will have uppercase letter if
 | 
			
		||||
    // the "Shift + <key>" combo was used or the Caps Lock
 | 
			
		||||
    // key was on. We turn to key to lowercase so the keybindings
 | 
			
		||||
    // work regardless of whether Caps Lock was on or not.
 | 
			
		||||
    const key = event.key.toLowerCase();
 | 
			
		||||
    const isBold = key === "b";
 | 
			
		||||
    const isItalic = key === "i" && !event.shiftKey;
 | 
			
		||||
    const isLink = key === "l" && event.shiftKey;
 | 
			
		||||
 | 
			
		||||
    // detect Cmd and Ctrl key
 | 
			
		||||
    const isCmdOrCtrl = common.has_mac_keyboard() ? event.metaKey : event.ctrlKey;
 | 
			
		||||
 | 
			
		||||
    if ((isBold || isItalic || isLink) && isCmdOrCtrl) {
 | 
			
		||||
        const range = textarea.range();
 | 
			
		||||
 | 
			
		||||
        if (isBold) {
 | 
			
		||||
            // Ctrl + B: Convert selected text to bold text
 | 
			
		||||
            compose_ui.wrap_text_with_markdown(textarea, "**", "**");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            if (!range.length) {
 | 
			
		||||
                textarea.caret(textarea.caret() - 2);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isItalic) {
 | 
			
		||||
            // Ctrl + I: Convert selected text to italic text
 | 
			
		||||
            compose_ui.wrap_text_with_markdown(textarea, "*", "*");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            if (!range.length) {
 | 
			
		||||
                textarea.caret(textarea.caret() - 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isLink) {
 | 
			
		||||
            // Ctrl + L: Insert a link to selected text
 | 
			
		||||
            compose_ui.wrap_text_with_markdown(textarea, "[", "](url)");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            const position = textarea.caret();
 | 
			
		||||
            const txt = textarea[0];
 | 
			
		||||
 | 
			
		||||
            // Include selected text in between [] parentheses and insert '(url)'
 | 
			
		||||
            // where "url" should be automatically selected.
 | 
			
		||||
            // Position of cursor depends on whether browser supports exec
 | 
			
		||||
            // command or not. So set cursor position accordingly.
 | 
			
		||||
            if (range.length > 0) {
 | 
			
		||||
                if (document.queryCommandEnabled("insertText")) {
 | 
			
		||||
                    txt.selectionStart = position - 4;
 | 
			
		||||
                    txt.selectionEnd = position - 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    txt.selectionStart = position + range.length + 3;
 | 
			
		||||
                    txt.selectionEnd = position + range.length + 6;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                textarea.caret(textarea.caret() - 6);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        compose_ui.autosize_textarea(textarea);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handle_keyup(event, textarea) {
 | 
			
		||||
    // Set the rtl class if the text has an rtl direction, remove it otherwise
 | 
			
		||||
    rtl.set_rtl_class_for_textarea(textarea);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function needs_subscribe_warning(user_id, stream_id) {
 | 
			
		||||
    // This returns true if all of these conditions are met:
 | 
			
		||||
    //  * the user is valid
 | 
			
		||||
@@ -630,10 +557,10 @@ export function initialize() {
 | 
			
		||||
        "#stream_message_recipient_stream,#stream_message_recipient_topic,#private_message_recipient",
 | 
			
		||||
    ).on("change", update_fade);
 | 
			
		||||
    $("#compose-textarea").on("keydown", (event) => {
 | 
			
		||||
        handle_keydown(event, $("#compose-textarea").expectOne());
 | 
			
		||||
        compose_ui.handle_keydown(event, $("#compose-textarea").expectOne());
 | 
			
		||||
    });
 | 
			
		||||
    $("#compose-textarea").on("keyup", (event) => {
 | 
			
		||||
        handle_keyup(event, $("#compose-textarea").expectOne());
 | 
			
		||||
        compose_ui.handle_keyup(event, $("#compose-textarea").expectOne());
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#compose-textarea").on("input propertychange", () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
import autosize from "autosize";
 | 
			
		||||
import $ from "jquery";
 | 
			
		||||
 | 
			
		||||
import * as common from "./common";
 | 
			
		||||
import {$t} from "./i18n";
 | 
			
		||||
import * as people from "./people";
 | 
			
		||||
import * as rtl from "./rtl";
 | 
			
		||||
import * as user_status from "./user_status";
 | 
			
		||||
 | 
			
		||||
let full_size_status = false; // true or false
 | 
			
		||||
@@ -194,3 +196,74 @@ export function make_compose_box_original_size() {
 | 
			
		||||
    $(".expand_composebox_button").show();
 | 
			
		||||
    $("#compose-textarea").trigger("focus");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handle_keydown(event, textarea) {
 | 
			
		||||
    // The event.key property will have uppercase letter if
 | 
			
		||||
    // the "Shift + <key>" combo was used or the Caps Lock
 | 
			
		||||
    // key was on. We turn to key to lowercase so the keybindings
 | 
			
		||||
    // work regardless of whether Caps Lock was on or not.
 | 
			
		||||
    const key = event.key.toLowerCase();
 | 
			
		||||
    const isBold = key === "b";
 | 
			
		||||
    const isItalic = key === "i" && !event.shiftKey;
 | 
			
		||||
    const isLink = key === "l" && event.shiftKey;
 | 
			
		||||
 | 
			
		||||
    // detect Cmd and Ctrl key
 | 
			
		||||
    const isCmdOrCtrl = common.has_mac_keyboard() ? event.metaKey : event.ctrlKey;
 | 
			
		||||
 | 
			
		||||
    if ((isBold || isItalic || isLink) && isCmdOrCtrl) {
 | 
			
		||||
        const range = textarea.range();
 | 
			
		||||
 | 
			
		||||
        if (isBold) {
 | 
			
		||||
            // Ctrl + B: Convert selected text to bold text
 | 
			
		||||
            wrap_text_with_markdown(textarea, "**", "**");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            if (!range.length) {
 | 
			
		||||
                textarea.caret(textarea.caret() - 2);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isItalic) {
 | 
			
		||||
            // Ctrl + I: Convert selected text to italic text
 | 
			
		||||
            wrap_text_with_markdown(textarea, "*", "*");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            if (!range.length) {
 | 
			
		||||
                textarea.caret(textarea.caret() - 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isLink) {
 | 
			
		||||
            // Ctrl + L: Insert a link to selected text
 | 
			
		||||
            wrap_text_with_markdown(textarea, "[", "](url)");
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            const position = textarea.caret();
 | 
			
		||||
            const txt = textarea[0];
 | 
			
		||||
 | 
			
		||||
            // Include selected text in between [] parentheses and insert '(url)'
 | 
			
		||||
            // where "url" should be automatically selected.
 | 
			
		||||
            // Position of cursor depends on whether browser supports exec
 | 
			
		||||
            // command or not. So set cursor position accordingly.
 | 
			
		||||
            if (range.length > 0) {
 | 
			
		||||
                if (document.queryCommandEnabled("insertText")) {
 | 
			
		||||
                    txt.selectionStart = position - 4;
 | 
			
		||||
                    txt.selectionEnd = position - 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    txt.selectionStart = position + range.length + 3;
 | 
			
		||||
                    txt.selectionEnd = position + range.length + 6;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                textarea.caret(textarea.caret() - 6);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        autosize_textarea(textarea);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handle_keyup(event, textarea) {
 | 
			
		||||
    // Set the rtl class if the text has an rtl direction, remove it otherwise
 | 
			
		||||
    rtl.set_rtl_class_for_textarea(textarea);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import * as blueslip from "./blueslip";
 | 
			
		||||
import * as channel from "./channel";
 | 
			
		||||
import * as compose from "./compose";
 | 
			
		||||
import * as compose_actions from "./compose_actions";
 | 
			
		||||
import * as compose_ui from "./compose_ui";
 | 
			
		||||
import * as composebox_typeahead from "./composebox_typeahead";
 | 
			
		||||
import * as condense from "./condense";
 | 
			
		||||
import * as confirm_dialog from "./confirm_dialog";
 | 
			
		||||
@@ -473,12 +474,12 @@ function edit_message(row, raw_content) {
 | 
			
		||||
                currently_editing_messages.get(rows.id(row)).listeners = listeners;
 | 
			
		||||
            }
 | 
			
		||||
            composebox_typeahead.initialize_compose_typeahead(edit_id);
 | 
			
		||||
            compose.handle_keyup(null, $(edit_id).expectOne());
 | 
			
		||||
            compose_ui.handle_keyup(null, $(edit_id).expectOne());
 | 
			
		||||
            $(edit_id).on("keydown", function (event) {
 | 
			
		||||
                compose.handle_keydown(event, $(this).expectOne());
 | 
			
		||||
                compose_ui.handle_keydown(event, $(this).expectOne());
 | 
			
		||||
            });
 | 
			
		||||
            $(edit_id).on("keyup", function (event) {
 | 
			
		||||
                compose.handle_keyup(event, $(this).expectOne());
 | 
			
		||||
                compose_ui.handle_keyup(event, $(this).expectOne());
 | 
			
		||||
            });
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,7 @@ EXEMPT_FILES = {
 | 
			
		||||
    "static/js/compose_fade.js",
 | 
			
		||||
    "static/js/compose_validate.js",
 | 
			
		||||
    "static/js/compose.js",
 | 
			
		||||
    "static/js/compose_ui.js",
 | 
			
		||||
    "static/js/condense.js",
 | 
			
		||||
    "static/js/confirm_dialog.js",
 | 
			
		||||
    "static/js/dialog_widget.js",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user