2020-08-01 03:43:15 +02:00
|
|
|
|
"use strict";
|
|
|
|
|
|
2020-11-30 23:46:45 +01:00
|
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
|
const {$t} = require("./lib/i18n");
|
|
|
|
|
const {mock_esm, set_global, zrequire} = require("./lib/namespace");
|
|
|
|
|
const {run_test} = require("./lib/test");
|
|
|
|
|
const $ = require("./lib/zjquery");
|
2020-12-01 00:02:16 +01:00
|
|
|
|
|
2021-07-28 18:23:34 +02:00
|
|
|
|
const noop = () => {};
|
|
|
|
|
|
|
|
|
|
set_global("navigator", {});
|
2017-12-08 16:17:20 +01:00
|
|
|
|
|
2023-03-06 04:20:23 +01:00
|
|
|
|
const autosize = () => {};
|
|
|
|
|
autosize.update = () => {};
|
|
|
|
|
mock_esm("autosize", {default: autosize});
|
|
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
|
mock_esm("../src/message_lists", {
|
2021-03-29 16:43:39 +02:00
|
|
|
|
current: {},
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-01 23:21:38 +01:00
|
|
|
|
const compose_ui = zrequire("compose_ui");
|
2023-06-27 01:40:25 +02:00
|
|
|
|
const stream_data = zrequire("stream_data");
|
2020-12-01 23:21:38 +01:00
|
|
|
|
const people = zrequire("people");
|
|
|
|
|
const user_status = zrequire("user_status");
|
2023-02-22 23:04:10 +01:00
|
|
|
|
const hash_util = mock_esm("../src/hash_util");
|
|
|
|
|
const channel = mock_esm("../src/channel");
|
2023-10-06 01:43:50 +02:00
|
|
|
|
const compose_reply = zrequire("compose_reply");
|
2021-03-29 16:43:39 +02:00
|
|
|
|
const message_lists = zrequire("message_lists");
|
2022-11-08 23:06:11 +01:00
|
|
|
|
const text_field_edit = mock_esm("text-field-edit");
|
2020-12-01 23:21:38 +01:00
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
|
const alice = {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
email: "alice@zulip.com",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
user_id: 101,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
full_name: "Alice",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
};
|
2019-11-02 00:06:25 +01:00
|
|
|
|
const bob = {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
email: "bob@zulip.com",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
user_id: 102,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
full_name: "Bob",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
};
|
|
|
|
|
|
2020-05-26 22:34:15 +02:00
|
|
|
|
people.add_active_user(alice);
|
|
|
|
|
people.add_active_user(bob);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2017-11-09 17:32:28 +01:00
|
|
|
|
function make_textbox(s) {
|
|
|
|
|
// Simulate a jQuery textbox for testing purposes.
|
2022-01-25 11:36:19 +01:00
|
|
|
|
const $widget = {};
|
2017-11-09 17:32:28 +01:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.s = s;
|
2022-11-08 23:06:11 +01:00
|
|
|
|
$widget[0] = "textarea";
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.focused = false;
|
2017-11-09 17:32:28 +01:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.caret = function (arg) {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
if (typeof arg === "number") {
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.pos = arg;
|
2020-09-24 07:50:36 +02:00
|
|
|
|
return this;
|
2017-11-09 17:32:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-08 23:06:11 +01:00
|
|
|
|
// Not used right now, but could be in future.
|
|
|
|
|
// if (arg) {
|
|
|
|
|
// $widget.insert_pos = $widget.pos;
|
|
|
|
|
// $widget.insert_text = arg;
|
|
|
|
|
// const before = $widget.s.slice(0, $widget.pos);
|
|
|
|
|
// const after = $widget.s.slice($widget.pos);
|
|
|
|
|
// $widget.s = before + arg + after;
|
|
|
|
|
// $widget.pos += arg.length;
|
|
|
|
|
// return this;
|
|
|
|
|
// }
|
2017-11-09 17:32:28 +01:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
return $widget.pos;
|
2017-11-09 17:32:28 +01:00
|
|
|
|
};
|
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.val = function (new_val) {
|
2022-04-09 23:44:38 +02:00
|
|
|
|
/* istanbul ignore if */
|
2018-08-15 03:55:44 +02:00
|
|
|
|
if (new_val) {
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$widget.s = new_val;
|
2020-09-24 07:50:36 +02:00
|
|
|
|
return this;
|
2018-08-15 03:55:44 +02:00
|
|
|
|
}
|
2022-01-25 11:36:19 +01:00
|
|
|
|
return $widget.s;
|
2017-11-09 17:32:28 +01:00
|
|
|
|
};
|
|
|
|
|
|
2023-10-07 04:39:49 +02:00
|
|
|
|
$widget.trigger = noop;
|
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
return $widget;
|
2017-11-09 17:32:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
|
run_test("autosize_textarea", ({override}) => {
|
2020-09-04 23:49:49 +02:00
|
|
|
|
const textarea_autosized = {};
|
|
|
|
|
|
2021-02-14 08:44:04 +01:00
|
|
|
|
override(autosize, "update", (textarea) => {
|
2020-09-04 23:49:49 +02:00
|
|
|
|
textarea_autosized.textarea = textarea;
|
|
|
|
|
textarea_autosized.autosized = true;
|
|
|
|
|
});
|
2021-02-14 08:44:04 +01:00
|
|
|
|
|
|
|
|
|
// Call autosize_textarea with an argument
|
|
|
|
|
const container = "container-stub";
|
|
|
|
|
compose_ui.autosize_textarea(container);
|
|
|
|
|
assert.equal(textarea_autosized.textarea, container);
|
2021-06-10 08:32:54 +02:00
|
|
|
|
assert.ok(textarea_autosized.autosized);
|
2020-09-04 23:49:49 +02:00
|
|
|
|
});
|
|
|
|
|
|
2022-11-08 23:06:11 +01:00
|
|
|
|
run_test("insert_syntax_and_focus", ({override}) => {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
$("#compose-textarea").val("xyz ");
|
2022-11-08 23:06:11 +01:00
|
|
|
|
$("#compose-textarea").caret = () => 4;
|
|
|
|
|
$("#compose-textarea")[0] = "compose-textarea";
|
|
|
|
|
// Since we are using a third party library, we just
|
|
|
|
|
// need to ensure it is being called with the right params.
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
|
|
|
|
assert.equal(syntax, ":octopus: ");
|
|
|
|
|
});
|
2020-07-15 01:29:15 +02:00
|
|
|
|
compose_ui.insert_syntax_and_focus(":octopus:");
|
2018-05-15 12:40:07 +02:00
|
|
|
|
});
|
2017-12-08 16:17:20 +01:00
|
|
|
|
|
2022-11-08 23:06:11 +01:00
|
|
|
|
run_test("smart_insert", ({override}) => {
|
2022-01-25 11:36:19 +01:00
|
|
|
|
let $textbox = make_textbox("abc");
|
|
|
|
|
$textbox.caret(4);
|
2022-11-08 23:06:11 +01:00
|
|
|
|
function override_with_expected_syntax(expected_syntax) {
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "textarea");
|
|
|
|
|
assert.equal(syntax, expected_syntax);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
override_with_expected_syntax(" :smile: ");
|
2023-01-30 12:05:09 +01:00
|
|
|
|
compose_ui.smart_insert_inline($textbox, ":smile:");
|
2022-01-25 11:36:19 +01:00
|
|
|
|
|
2022-11-08 23:06:11 +01:00
|
|
|
|
override_with_expected_syntax(" :airplane: ");
|
2023-01-30 12:05:09 +01:00
|
|
|
|
compose_ui.smart_insert_inline($textbox, ":airplane:");
|
2022-01-25 11:36:19 +01:00
|
|
|
|
|
|
|
|
|
$textbox.caret(0);
|
2022-11-08 23:06:11 +01:00
|
|
|
|
override_with_expected_syntax(":octopus: ");
|
2023-01-30 12:05:09 +01:00
|
|
|
|
compose_ui.smart_insert_inline($textbox, ":octopus:");
|
2022-01-25 11:36:19 +01:00
|
|
|
|
|
|
|
|
|
$textbox.caret($textbox.val().length);
|
2022-11-08 23:06:11 +01:00
|
|
|
|
override_with_expected_syntax(" :heart: ");
|
2023-01-30 12:05:09 +01:00
|
|
|
|
compose_ui.smart_insert_inline($textbox, ":heart:");
|
2017-11-09 17:57:59 +01:00
|
|
|
|
|
2019-02-27 22:17:27 +01:00
|
|
|
|
// Test handling of spaces for ```quote
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$textbox = make_textbox("");
|
|
|
|
|
$textbox.caret(0);
|
2023-01-30 12:05:09 +01:00
|
|
|
|
override_with_expected_syntax("```quote\nquoted message\n```\n\n");
|
|
|
|
|
compose_ui.smart_insert_block($textbox, "```quote\nquoted message\n```");
|
2022-01-25 11:36:19 +01:00
|
|
|
|
|
|
|
|
|
$textbox = make_textbox("");
|
|
|
|
|
$textbox.caret(0);
|
2023-01-30 12:05:09 +01:00
|
|
|
|
override_with_expected_syntax("translated: [Quoting…]\n\n");
|
|
|
|
|
compose_ui.smart_insert_block($textbox, "translated: [Quoting…]");
|
2022-01-25 11:36:19 +01:00
|
|
|
|
|
|
|
|
|
$textbox = make_textbox("abc");
|
|
|
|
|
$textbox.caret(3);
|
2023-01-30 12:05:09 +01:00
|
|
|
|
override_with_expected_syntax("\n\n test with space\n\n");
|
|
|
|
|
compose_ui.smart_insert_block($textbox, " test with space");
|
2019-02-27 22:17:27 +01:00
|
|
|
|
|
2017-11-09 17:57:59 +01:00
|
|
|
|
// Note that we don't have any special logic for strings that are
|
|
|
|
|
// already surrounded by spaces, since we are usually inserting things
|
|
|
|
|
// like emojis and file links.
|
2018-05-15 12:40:07 +02:00
|
|
|
|
});
|
2017-11-09 17:32:28 +01:00
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
run_test("replace_syntax", ({override}) => {
|
2022-12-14 05:54:01 +01:00
|
|
|
|
const $textbox = make_textbox("aBca$$");
|
|
|
|
|
$textbox.caret(2);
|
2022-11-21 08:25:47 +01:00
|
|
|
|
override(text_field_edit, "replace", (elt, old_syntax, new_syntax) => {
|
2022-12-14 05:54:01 +01:00
|
|
|
|
assert.equal(elt, "textarea");
|
2022-11-21 08:25:47 +01:00
|
|
|
|
assert.equal(old_syntax, "a");
|
|
|
|
|
assert.equal(new_syntax(), "A");
|
|
|
|
|
});
|
2023-07-31 20:35:07 +02:00
|
|
|
|
let prev_caret = $textbox.caret();
|
2022-12-14 05:54:01 +01:00
|
|
|
|
compose_ui.replace_syntax("a", "A", $textbox);
|
2023-07-31 20:35:07 +02:00
|
|
|
|
assert.equal(prev_caret, $textbox.caret());
|
2019-04-13 19:50:25 +02:00
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
override(text_field_edit, "replace", (elt, old_syntax, new_syntax) => {
|
2022-12-14 05:54:01 +01:00
|
|
|
|
assert.equal(elt, "textarea");
|
2022-11-21 08:25:47 +01:00
|
|
|
|
assert.equal(old_syntax, "Bca");
|
|
|
|
|
assert.equal(new_syntax(), "$$\\pi$$");
|
|
|
|
|
});
|
2022-12-14 05:54:01 +01:00
|
|
|
|
|
2019-04-13 19:50:25 +02:00
|
|
|
|
// Verify we correctly handle `$`s in the replacement syntax
|
2022-12-14 05:54:01 +01:00
|
|
|
|
// and that on replacing with a different length string, the
|
|
|
|
|
// cursor is shifted accordingly as expected
|
|
|
|
|
$textbox.caret(5);
|
2023-07-31 20:35:07 +02:00
|
|
|
|
prev_caret = $textbox.caret();
|
2022-12-14 05:54:01 +01:00
|
|
|
|
compose_ui.replace_syntax("Bca", "$$\\pi$$", $textbox);
|
2023-07-31 20:35:07 +02:00
|
|
|
|
assert.equal(prev_caret + "$$\\pi$$".length - "Bca".length, $textbox.caret());
|
2018-08-15 03:55:44 +02:00
|
|
|
|
});
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
|
run_test("compute_placeholder_text", () => {
|
2019-11-02 00:06:25 +01:00
|
|
|
|
let opts = {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
message_type: "stream",
|
2023-09-26 20:28:39 +02:00
|
|
|
|
stream_id: undefined,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
topic: "",
|
|
|
|
|
private_message_recipient: "",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Stream narrows
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(
|
|
|
|
|
compose_ui.compute_placeholder_text(opts),
|
|
|
|
|
$t({defaultMessage: "Compose your message here"}),
|
|
|
|
|
);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2023-06-27 01:40:25 +02:00
|
|
|
|
const stream_all = {
|
|
|
|
|
subscribed: true,
|
|
|
|
|
name: "all",
|
|
|
|
|
stream_id: 2,
|
|
|
|
|
};
|
|
|
|
|
stream_data.add_sub(stream_all);
|
|
|
|
|
opts.stream_id = stream_all.stream_id;
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(compose_ui.compute_placeholder_text(opts), $t({defaultMessage: "Message #all"}));
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
|
|
|
|
opts.topic = "Test";
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(
|
|
|
|
|
compose_ui.compute_placeholder_text(opts),
|
|
|
|
|
$t({defaultMessage: "Message #all > Test"}),
|
|
|
|
|
);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2023-06-16 17:37:19 +02:00
|
|
|
|
// direct message narrows
|
2019-07-23 20:13:43 +02:00
|
|
|
|
opts = {
|
2020-07-15 01:29:15 +02:00
|
|
|
|
message_type: "private",
|
2023-09-26 20:28:39 +02:00
|
|
|
|
stream_id: undefined,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
topic: "",
|
|
|
|
|
private_message_recipient: "",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
};
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(
|
|
|
|
|
compose_ui.compute_placeholder_text(opts),
|
|
|
|
|
$t({defaultMessage: "Compose your message here"}),
|
|
|
|
|
);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
|
opts.private_message_recipient = "bob@zulip.com";
|
2019-07-23 20:13:43 +02:00
|
|
|
|
user_status.set_status_text({
|
|
|
|
|
user_id: bob.user_id,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
status_text: "out to lunch",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
});
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(
|
|
|
|
|
compose_ui.compute_placeholder_text(opts),
|
|
|
|
|
$t({defaultMessage: "Message Bob (out to lunch)"}),
|
|
|
|
|
);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
|
opts.private_message_recipient = "alice@zulip.com";
|
2019-07-23 20:13:43 +02:00
|
|
|
|
user_status.set_status_text({
|
|
|
|
|
user_id: alice.user_id,
|
2020-07-15 01:29:15 +02:00
|
|
|
|
status_text: "",
|
2019-07-23 20:13:43 +02:00
|
|
|
|
});
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(compose_ui.compute_placeholder_text(opts), $t({defaultMessage: "Message Alice"}));
|
2019-07-23 20:13:43 +02:00
|
|
|
|
|
2023-06-16 17:37:19 +02:00
|
|
|
|
// group direct message
|
2020-07-15 01:29:15 +02:00
|
|
|
|
opts.private_message_recipient = "alice@zulip.com,bob@zulip.com";
|
2021-04-13 06:51:54 +02:00
|
|
|
|
assert.equal(
|
|
|
|
|
compose_ui.compute_placeholder_text(opts),
|
|
|
|
|
$t({defaultMessage: "Message Alice, Bob"}),
|
|
|
|
|
);
|
2019-07-23 20:13:43 +02:00
|
|
|
|
});
|
2021-03-29 16:43:39 +02:00
|
|
|
|
|
2022-01-08 10:27:06 +01:00
|
|
|
|
run_test("quote_and_reply", ({override, override_rewire}) => {
|
2023-07-26 22:07:21 +02:00
|
|
|
|
const devel_stream = {
|
|
|
|
|
subscribed: false,
|
|
|
|
|
name: "devel",
|
|
|
|
|
stream_id: 20,
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-29 16:43:39 +02:00
|
|
|
|
const selected_message = {
|
|
|
|
|
type: "stream",
|
2023-07-26 22:07:21 +02:00
|
|
|
|
stream_id: devel_stream.stream_id,
|
2021-03-29 16:43:39 +02:00
|
|
|
|
topic: "python",
|
|
|
|
|
sender_full_name: "Steve Stephenson",
|
|
|
|
|
sender_id: 90,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
override(
|
|
|
|
|
hash_util,
|
2022-03-01 19:14:26 +01:00
|
|
|
|
"by_conversation_and_time_url",
|
2021-03-29 16:43:39 +02:00
|
|
|
|
() => "https://chat.zulip.org/#narrow/stream/92-learning/topic/Tornado",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
override(message_lists.current, "selected_message", () => selected_message);
|
|
|
|
|
override(message_lists.current, "selected_id", () => 100);
|
|
|
|
|
|
|
|
|
|
let success_function;
|
|
|
|
|
override(channel, "get", (opts) => {
|
|
|
|
|
success_function = opts.success;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// zjquery does not simulate caret handling, so we provide
|
|
|
|
|
// our own versions of val() and caret()
|
|
|
|
|
let textarea_val = "";
|
|
|
|
|
let textarea_caret_pos;
|
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
$("#compose-textarea").val = function () {
|
|
|
|
|
return textarea_val;
|
2021-03-29 16:43:39 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$("#compose-textarea").caret = function (arg) {
|
|
|
|
|
if (arg === undefined) {
|
|
|
|
|
return textarea_caret_pos;
|
|
|
|
|
}
|
2020-12-31 12:53:54 +01:00
|
|
|
|
if (typeof arg === "number") {
|
|
|
|
|
textarea_caret_pos = arg;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2021-03-29 16:43:39 +02:00
|
|
|
|
|
2023-01-30 12:05:09 +01:00
|
|
|
|
/* This next block of mocking code is currently unused, but
|
|
|
|
|
is preserved, since it may be useful in the future. */
|
|
|
|
|
/* istanbul ignore next */
|
|
|
|
|
{
|
|
|
|
|
if (typeof arg !== "string") {
|
|
|
|
|
console.info(arg);
|
|
|
|
|
throw new Error("We expected the actual code to pass in a string.");
|
|
|
|
|
}
|
2021-03-29 16:43:39 +02:00
|
|
|
|
|
2023-01-30 12:05:09 +01:00
|
|
|
|
const before = textarea_val.slice(0, textarea_caret_pos);
|
|
|
|
|
const after = textarea_val.slice(textarea_caret_pos);
|
|
|
|
|
|
|
|
|
|
textarea_val = before + arg + after;
|
|
|
|
|
textarea_caret_pos += arg.length;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2021-03-29 16:43:39 +02:00
|
|
|
|
};
|
2022-11-08 23:06:11 +01:00
|
|
|
|
$("#compose-textarea")[0] = "compose-textarea";
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
2023-01-30 12:05:09 +01:00
|
|
|
|
assert.equal(syntax, "\n\ntranslated: [Quoting…]\n\n");
|
2022-11-08 23:06:11 +01:00
|
|
|
|
});
|
2021-03-29 16:43:39 +02:00
|
|
|
|
|
|
|
|
|
function set_compose_content_with_caret(content) {
|
|
|
|
|
const caret_position = content.indexOf("%");
|
|
|
|
|
content = content.slice(0, caret_position) + content.slice(caret_position + 1); // remove the "%"
|
|
|
|
|
textarea_val = content;
|
|
|
|
|
textarea_caret_pos = caret_position;
|
|
|
|
|
$("#compose-textarea").trigger("focus");
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-31 12:53:54 +01:00
|
|
|
|
function reset_test_state() {
|
|
|
|
|
// Reset `raw_content` property of `selected_message`.
|
|
|
|
|
delete selected_message.raw_content;
|
|
|
|
|
|
|
|
|
|
// Reset compose-box state.
|
|
|
|
|
textarea_val = "";
|
|
|
|
|
textarea_caret_pos = 0;
|
|
|
|
|
$("#compose-textarea").trigger("blur");
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
function override_with_quote_text(quote_text) {
|
|
|
|
|
override(text_field_edit, "replace", (elt, old_syntax, new_syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
|
|
|
|
assert.equal(old_syntax, "translated: [Quoting…]");
|
|
|
|
|
assert.equal(
|
|
|
|
|
new_syntax(),
|
|
|
|
|
"translated: @_**Steve Stephenson|90** [said](https://chat.zulip.org/#narrow/stream/92-learning/topic/Tornado):\n" +
|
|
|
|
|
"```quote\n" +
|
|
|
|
|
`${quote_text}\n` +
|
|
|
|
|
"```",
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let quote_text = "Testing caret position";
|
|
|
|
|
override_with_quote_text(quote_text);
|
2021-03-29 16:43:39 +02:00
|
|
|
|
set_compose_content_with_caret("hello %there"); // "%" is used to encode/display position of focus before change
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2021-03-29 16:43:39 +02:00
|
|
|
|
|
|
|
|
|
success_function({
|
2022-11-21 08:25:47 +01:00
|
|
|
|
raw_content: quote_text,
|
2021-03-29 16:43:39 +02:00
|
|
|
|
});
|
2020-12-31 12:53:54 +01:00
|
|
|
|
|
|
|
|
|
reset_test_state();
|
|
|
|
|
|
|
|
|
|
// If the caret is initially positioned at 0, it should not
|
2023-01-30 12:05:09 +01:00
|
|
|
|
// add newlines before the quoted message.
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
|
|
|
|
assert.equal(syntax, "translated: [Quoting…]\n\n");
|
|
|
|
|
});
|
2020-12-31 12:53:54 +01:00
|
|
|
|
set_compose_content_with_caret("%hello there");
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2020-12-31 12:53:54 +01:00
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
quote_text = "Testing with caret initially positioned at 0.";
|
|
|
|
|
override_with_quote_text(quote_text);
|
2020-12-31 12:53:54 +01:00
|
|
|
|
success_function({
|
2022-11-21 08:25:47 +01:00
|
|
|
|
raw_content: quote_text,
|
2020-12-31 12:53:54 +01:00
|
|
|
|
});
|
|
|
|
|
|
2023-10-06 01:43:50 +02:00
|
|
|
|
override_rewire(compose_reply, "respond_to_message", () => {
|
2020-12-31 12:53:54 +01:00
|
|
|
|
// Reset compose state to replicate the re-opening of compose-box.
|
|
|
|
|
textarea_val = "";
|
|
|
|
|
textarea_caret_pos = 0;
|
|
|
|
|
$("#compose-textarea").trigger("focus");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
reset_test_state();
|
|
|
|
|
|
|
|
|
|
// If the compose-box is close, or open with no content while
|
|
|
|
|
// quoting a message, the quoted message should be placed
|
|
|
|
|
// at the beginning of compose-box.
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2020-12-31 12:53:54 +01:00
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
quote_text = "Testing with compose-box closed initially.";
|
|
|
|
|
override_with_quote_text(quote_text);
|
2020-12-31 12:53:54 +01:00
|
|
|
|
success_function({
|
2022-11-21 08:25:47 +01:00
|
|
|
|
raw_content: quote_text,
|
2020-12-31 12:53:54 +01:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
reset_test_state();
|
|
|
|
|
|
|
|
|
|
// If the compose-box is already open while quoting a message,
|
|
|
|
|
// but contains content like `\n\n \n` (only whitespaces and
|
|
|
|
|
// newlines), the compose-box should re-open and thus the quoted
|
|
|
|
|
// message should start from the beginning of compose-box.
|
|
|
|
|
set_compose_content_with_caret(" \n\n \n %");
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2020-12-31 12:53:54 +01:00
|
|
|
|
|
2022-11-21 08:25:47 +01:00
|
|
|
|
quote_text = "Testing with compose-box containing whitespaces and newlines only.";
|
|
|
|
|
override_with_quote_text(quote_text);
|
2020-12-31 12:53:54 +01:00
|
|
|
|
success_function({
|
2023-01-30 12:05:09 +01:00
|
|
|
|
raw_content: quote_text,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
reset_test_state();
|
|
|
|
|
|
|
|
|
|
// When there is already 1 newline before and after the caret,
|
|
|
|
|
// only 1 newline is added before and after the quoted message.
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
|
|
|
|
assert.equal(syntax, "\ntranslated: [Quoting…]\n");
|
|
|
|
|
});
|
|
|
|
|
set_compose_content_with_caret("1st line\n%\n2nd line");
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2023-01-30 12:05:09 +01:00
|
|
|
|
|
|
|
|
|
quote_text = "Testing with caret on a new line between 2 lines of text.";
|
|
|
|
|
override_with_quote_text(quote_text);
|
|
|
|
|
success_function({
|
|
|
|
|
raw_content: quote_text,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
reset_test_state();
|
|
|
|
|
|
|
|
|
|
// When there are many (>=2) newlines before and after the caret,
|
|
|
|
|
// no newline is added before or after the quoted message.
|
|
|
|
|
override(text_field_edit, "insert", (elt, syntax) => {
|
|
|
|
|
assert.equal(elt, "compose-textarea");
|
|
|
|
|
assert.equal(syntax, "translated: [Quoting…]");
|
|
|
|
|
});
|
|
|
|
|
set_compose_content_with_caret("lots of\n\n\n\n%\n\n\nnewlines");
|
2023-10-06 01:43:50 +02:00
|
|
|
|
compose_reply.quote_and_reply();
|
2023-01-30 12:05:09 +01:00
|
|
|
|
|
|
|
|
|
quote_text = "Testing with caret on a new line between many empty newlines.";
|
|
|
|
|
override_with_quote_text(quote_text);
|
|
|
|
|
success_function({
|
2022-11-21 08:25:47 +01:00
|
|
|
|
raw_content: quote_text,
|
2020-12-31 12:53:54 +01:00
|
|
|
|
});
|
2021-03-29 16:43:39 +02:00
|
|
|
|
});
|
2021-05-17 13:15:11 +02:00
|
|
|
|
|
2021-07-15 21:26:16 +02:00
|
|
|
|
run_test("set_compose_box_top", () => {
|
|
|
|
|
let compose_top = "";
|
|
|
|
|
$("#compose").css = (arg, val) => {
|
|
|
|
|
assert.equal(arg, "top");
|
|
|
|
|
compose_top = val;
|
|
|
|
|
};
|
|
|
|
|
|
2023-05-20 16:30:21 +02:00
|
|
|
|
$("#navbar-fixed-container").set_height(50);
|
2021-07-15 21:26:16 +02:00
|
|
|
|
compose_ui.set_compose_box_top(true);
|
|
|
|
|
assert.equal(compose_top, "50px");
|
|
|
|
|
|
|
|
|
|
compose_ui.set_compose_box_top(false);
|
|
|
|
|
assert.equal(compose_top, "");
|
|
|
|
|
});
|
|
|
|
|
|
2022-01-08 10:27:06 +01:00
|
|
|
|
run_test("test_compose_height_changes", ({override, override_rewire}) => {
|
2021-05-17 13:15:11 +02:00
|
|
|
|
let autosize_destroyed = false;
|
|
|
|
|
override(autosize, "destroy", () => {
|
|
|
|
|
autosize_destroyed = true;
|
|
|
|
|
});
|
|
|
|
|
|
2021-07-15 21:26:16 +02:00
|
|
|
|
let compose_box_top_set = false;
|
2022-01-08 10:27:06 +01:00
|
|
|
|
override_rewire(compose_ui, "set_compose_box_top", (set_top) => {
|
2021-07-15 21:26:16 +02:00
|
|
|
|
compose_box_top_set = set_top;
|
|
|
|
|
});
|
|
|
|
|
|
2021-05-17 13:15:11 +02:00
|
|
|
|
compose_ui.make_compose_box_full_size();
|
|
|
|
|
assert.ok($("#compose").hasClass("compose-fullscreen"));
|
|
|
|
|
assert.ok(compose_ui.is_full_size());
|
|
|
|
|
assert.ok(autosize_destroyed);
|
2021-07-15 21:26:16 +02:00
|
|
|
|
assert.ok(compose_box_top_set);
|
2021-05-17 13:15:11 +02:00
|
|
|
|
|
|
|
|
|
compose_ui.make_compose_box_original_size();
|
|
|
|
|
assert.ok(!$("#compose").hasClass("compose-fullscreen"));
|
|
|
|
|
assert.ok(!compose_ui.is_full_size());
|
2021-07-15 21:26:16 +02:00
|
|
|
|
assert.ok(!compose_box_top_set);
|
2021-05-17 13:15:11 +02:00
|
|
|
|
});
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
2023-09-25 05:29:20 +02:00
|
|
|
|
let set_text = "";
|
|
|
|
|
let wrap_selection_called = false;
|
|
|
|
|
let wrap_syntax_start = "";
|
|
|
|
|
let wrap_syntax_end = "";
|
|
|
|
|
|
|
|
|
|
function reset_state() {
|
|
|
|
|
set_text = "";
|
|
|
|
|
wrap_selection_called = false;
|
|
|
|
|
wrap_syntax_start = "";
|
|
|
|
|
wrap_syntax_end = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const $textarea = $("#compose-textarea");
|
|
|
|
|
$textarea.get = () => ({
|
|
|
|
|
setSelectionRange(start, end) {
|
|
|
|
|
$textarea.range = () => ({
|
|
|
|
|
start,
|
|
|
|
|
end,
|
|
|
|
|
text: $textarea.val().slice(start, end),
|
|
|
|
|
length: end - start,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function init_textarea(val, range) {
|
|
|
|
|
$textarea.val = () => val;
|
|
|
|
|
$textarea.range = () => range;
|
|
|
|
|
}
|
2021-09-04 17:47:27 +02:00
|
|
|
|
|
2023-09-25 05:29:20 +02:00
|
|
|
|
run_test("format_text - bold and italic", ({override}) => {
|
2023-06-29 21:59:08 +02:00
|
|
|
|
override(text_field_edit, "set", (_field, text) => {
|
2022-11-08 23:06:11 +01:00
|
|
|
|
set_text = text;
|
|
|
|
|
});
|
2023-09-25 05:29:20 +02:00
|
|
|
|
override(text_field_edit, "wrapSelection", (_field, syntax_start, syntax_end) => {
|
2022-11-08 23:06:11 +01:00
|
|
|
|
wrap_selection_called = true;
|
2023-09-25 05:29:20 +02:00
|
|
|
|
wrap_syntax_start = syntax_start;
|
|
|
|
|
wrap_syntax_end = syntax_end || syntax_start;
|
2021-09-04 17:47:27 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const italic_syntax = "*";
|
|
|
|
|
const bold_syntax = "**";
|
|
|
|
|
|
|
|
|
|
// Bold selected text
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("abc", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 3,
|
|
|
|
|
text: "abc",
|
|
|
|
|
length: 3,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "bold");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "");
|
|
|
|
|
assert.equal(wrap_selection_called, true);
|
2023-09-25 05:29:20 +02:00
|
|
|
|
assert.equal(wrap_syntax_start, bold_syntax);
|
|
|
|
|
assert.equal(wrap_syntax_end, bold_syntax);
|
2021-09-04 17:47:27 +02:00
|
|
|
|
|
|
|
|
|
// Undo bold selected text, syntax not selected
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("**abc**", {
|
|
|
|
|
start: 2,
|
|
|
|
|
end: 5,
|
|
|
|
|
text: "abc",
|
2022-07-11 17:41:13 +02:00
|
|
|
|
length: 3,
|
2021-09-04 17:47:27 +02:00
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "bold");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "abc");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo bold selected text, syntax selected
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("**abc**", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 7,
|
|
|
|
|
text: "**abc**",
|
|
|
|
|
length: 7,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "bold");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "abc");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Italic selected text
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("abc", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 3,
|
|
|
|
|
text: "abc",
|
|
|
|
|
length: 3,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "italic");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "");
|
|
|
|
|
assert.equal(wrap_selection_called, true);
|
2023-09-25 05:29:20 +02:00
|
|
|
|
assert.equal(wrap_syntax_start, italic_syntax);
|
|
|
|
|
assert.equal(wrap_syntax_end, italic_syntax);
|
2021-09-04 17:47:27 +02:00
|
|
|
|
|
|
|
|
|
// Undo italic selected text, syntax not selected
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("*abc*", {
|
|
|
|
|
start: 1,
|
|
|
|
|
end: 4,
|
|
|
|
|
text: "abc",
|
|
|
|
|
length: 3,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "italic");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "abc");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo italic selected text, syntax selected
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("*abc*", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 5,
|
|
|
|
|
text: "*abc*",
|
|
|
|
|
length: 5,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "italic");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "abc");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo bold selected text, text is both italic and bold, syntax not selected.
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("***abc***", {
|
|
|
|
|
start: 3,
|
|
|
|
|
end: 6,
|
|
|
|
|
text: "abc",
|
|
|
|
|
length: 3,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "bold");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "*abc*");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo bold selected text, text is both italic and bold, syntax selected.
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("***abc***", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 9,
|
|
|
|
|
text: "***abc***",
|
|
|
|
|
length: 9,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "bold");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "*abc*");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo italic selected text, text is both italic and bold, syntax not selected.
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("***abc***", {
|
|
|
|
|
start: 3,
|
|
|
|
|
end: 6,
|
|
|
|
|
text: "abc",
|
|
|
|
|
length: 3,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "italic");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "**abc**");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Undo italic selected text, text is both italic and bold, syntax selected.
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("***abc***", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 9,
|
|
|
|
|
text: "***abc***",
|
|
|
|
|
length: 9,
|
|
|
|
|
});
|
2022-01-25 11:36:19 +01:00
|
|
|
|
compose_ui.format_text($textarea, "italic");
|
2021-09-04 17:47:27 +02:00
|
|
|
|
assert.equal(set_text, "**abc**");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
2022-07-11 17:41:13 +02:00
|
|
|
|
|
|
|
|
|
// Test bulleted list addition
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("first_item\nsecond_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 22,
|
|
|
|
|
text: "first_item\nsecond_item",
|
|
|
|
|
length: 22,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "bulleted");
|
|
|
|
|
assert.equal(set_text, "- first_item\n- second_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test bulleted list addition with newline at start
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("\nfirst_item\nsecond_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 23,
|
|
|
|
|
text: "\nfirst_item\nsecond_item",
|
|
|
|
|
length: 23,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "bulleted");
|
|
|
|
|
assert.equal(set_text, "- \n- first_item\n- second_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test bulleted list removal
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("- first_item\n- second_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 26,
|
|
|
|
|
text: "- first_item\n- second_item",
|
|
|
|
|
length: 26,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "bulleted");
|
|
|
|
|
assert.equal(set_text, "first_item\nsecond_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test bulleted list removal with *s
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("* first_item\n* second_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 26,
|
|
|
|
|
text: "* first_item\n* second_item",
|
|
|
|
|
length: 26,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "bulleted");
|
|
|
|
|
assert.equal(set_text, "first_item\nsecond_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
2022-07-12 10:55:06 +02:00
|
|
|
|
|
|
|
|
|
// Test numbered list toggling on
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("first_item\nsecond_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 22,
|
|
|
|
|
text: "first_item\nsecond_item",
|
|
|
|
|
length: 22,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "numbered");
|
|
|
|
|
assert.equal(set_text, "1. first_item\n2. second_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test numbered list toggling off
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("1. first_item\n2. second_item", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 28,
|
|
|
|
|
text: "1. first_item\n2. second_item",
|
|
|
|
|
length: 28,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "numbered");
|
|
|
|
|
assert.equal(set_text, "first_item\nsecond_item");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test numbered list toggling with newline at end
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("first_item\nsecond_item\n", {
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 23,
|
|
|
|
|
text: "first_item\nsecond_item\n",
|
|
|
|
|
length: 23,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "numbered");
|
|
|
|
|
assert.equal(set_text, "1. first_item\n2. second_item\n");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
|
|
|
|
|
|
|
|
|
// Test numbered list toggling on with partially selected lines
|
|
|
|
|
reset_state();
|
|
|
|
|
init_textarea("before_first\nfirst_item\nsecond_item\nafter_last", {
|
|
|
|
|
start: 15,
|
|
|
|
|
end: 33,
|
|
|
|
|
text: "rst_item\nsecond_it",
|
|
|
|
|
length: 18,
|
|
|
|
|
});
|
|
|
|
|
compose_ui.format_text($textarea, "numbered");
|
|
|
|
|
// Notice the blank lines inserted right before and after the list to visually demarcate it.
|
|
|
|
|
// Had the blank line after `second_item` not been inserted, `after_last` would have been
|
|
|
|
|
// (wrongly) indented as part of the list's last item too.
|
|
|
|
|
assert.equal(set_text, "before_first\n\n1. first_item\n2. second_item\n\nafter_last");
|
|
|
|
|
assert.equal(wrap_selection_called, false);
|
2021-09-04 17:47:27 +02:00
|
|
|
|
});
|
|
|
|
|
|
2022-01-08 10:27:06 +01:00
|
|
|
|
run_test("markdown_shortcuts", ({override_rewire}) => {
|
2021-06-22 10:31:40 +02:00
|
|
|
|
let format_text_type;
|
2023-06-29 21:59:08 +02:00
|
|
|
|
override_rewire(compose_ui, "format_text", (_$textarea, type) => {
|
2021-06-22 10:31:40 +02:00
|
|
|
|
format_text_type = type;
|
|
|
|
|
});
|
|
|
|
|
|
2021-07-28 18:23:34 +02:00
|
|
|
|
const event = {
|
|
|
|
|
key: "b",
|
|
|
|
|
target: {
|
|
|
|
|
id: "compose-textarea",
|
|
|
|
|
},
|
|
|
|
|
stopPropagation: noop,
|
|
|
|
|
preventDefault: noop,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function all_markdown_test(isCtrl, isCmd) {
|
|
|
|
|
// 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"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, "bold");
|
|
|
|
|
format_text_type = undefined;
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
// Test italic:
|
|
|
|
|
// Mac = Cmd+I
|
|
|
|
|
// Windows/Linux = Ctrl+I
|
|
|
|
|
// We use event.key = "I" to emulate user using Caps Lock key.
|
|
|
|
|
event.key = "I";
|
|
|
|
|
event.shiftKey = false;
|
|
|
|
|
compose_ui.handle_keydown(event, $("#compose-textarea"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, "italic");
|
|
|
|
|
format_text_type = undefined;
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
// Test link insertion:
|
|
|
|
|
// Mac = Cmd+Shift+L
|
|
|
|
|
// Windows/Linux = Ctrl+Shift+L
|
|
|
|
|
event.key = "l";
|
|
|
|
|
event.shiftKey = true;
|
|
|
|
|
compose_ui.handle_keydown(event, $("#compose-textarea"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, "link");
|
|
|
|
|
format_text_type = undefined;
|
2021-07-28 18:23:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
|
event.ctrlKey = isCtrl;
|
2021-06-22 10:31:40 +02:00
|
|
|
|
event.metaKey = isCmd;
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
event.key = "b";
|
|
|
|
|
compose_ui.handle_keydown(event, $("#compose-textarea"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, undefined);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
event.key = "i";
|
|
|
|
|
event.shiftKey = false;
|
|
|
|
|
compose_ui.handle_keydown(event, $("#compose-textarea"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, undefined);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
event.key = "l";
|
|
|
|
|
event.shiftKey = true;
|
|
|
|
|
compose_ui.handle_keydown(event, $("#compose-textarea"));
|
2021-06-22 10:31:40 +02:00
|
|
|
|
assert.equal(format_text_type, undefined);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 = "";
|
|
|
|
|
|
|
|
|
|
// 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:
|
|
|
|
|
// 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", () => {
|
2022-01-25 11:36:19 +01:00
|
|
|
|
const $textarea = $("#compose-textarea");
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
|
|
|
|
const event = {
|
|
|
|
|
key: "A",
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
assert.equal($textarea.hasClass("rtl"), false);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$textarea.val("```quote\nمرحبا");
|
2021-07-28 18:23:34 +02:00
|
|
|
|
compose_ui.handle_keyup(event, $("#compose-textarea"));
|
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
assert.equal($textarea.hasClass("rtl"), true);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
$textarea.val("```quote foo");
|
|
|
|
|
compose_ui.handle_keyup(event, $textarea);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
|
assert.equal($textarea.hasClass("rtl"), false);
|
2021-07-28 18:23:34 +02:00
|
|
|
|
});
|
2023-04-27 23:45:30 +02:00
|
|
|
|
|
|
|
|
|
const get_focus_area = compose_ui._get_focus_area;
|
|
|
|
|
run_test("get_focus_area", () => {
|
|
|
|
|
assert.equal(get_focus_area("private", {}), "#private_message_recipient");
|
|
|
|
|
assert.equal(
|
|
|
|
|
get_focus_area("private", {
|
|
|
|
|
private_message_recipient: "bob@example.com",
|
|
|
|
|
}),
|
|
|
|
|
"#compose-textarea",
|
|
|
|
|
);
|
2023-07-19 16:09:53 +02:00
|
|
|
|
assert.equal(get_focus_area("stream", {}), "#compose_select_recipient_widget_wrapper");
|
2023-04-27 23:45:30 +02:00
|
|
|
|
assert.equal(
|
2023-06-27 01:40:25 +02:00
|
|
|
|
get_focus_area("stream", {stream_name: "fun", stream_id: 4}),
|
|
|
|
|
"#stream_message_recipient_topic",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
get_focus_area("stream", {stream_name: "fun", stream_id: 4, topic: "more"}),
|
|
|
|
|
"#compose-textarea",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
get_focus_area("stream", {
|
|
|
|
|
stream_id: 4,
|
|
|
|
|
topic: "more",
|
2023-10-03 21:43:55 +02:00
|
|
|
|
trigger: "clear topic button",
|
2023-06-27 01:40:25 +02:00
|
|
|
|
}),
|
2023-04-27 23:45:30 +02:00
|
|
|
|
"#stream_message_recipient_topic",
|
|
|
|
|
);
|
|
|
|
|
});
|