mirror of
https://github.com/zulip/zulip.git
synced 2025-11-19 14:08:23 +00:00
docs: Fix capitalization of keyboard keys.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Tim Abbott
parent
c155403884
commit
fb2e56e3c9
@@ -217,11 +217,11 @@ Two editors often available by default on Linux systems are:
|
|||||||
* **Nano**: A very simple, beginner-friendly editor. However, it lacks a lot of
|
* **Nano**: A very simple, beginner-friendly editor. However, it lacks a lot of
|
||||||
features useful for programming, such as syntax highlighting, so we only
|
features useful for programming, such as syntax highlighting, so we only
|
||||||
recommended it for quick edits to things like configuration files. Launch by
|
recommended it for quick edits to things like configuration files. Launch by
|
||||||
running command `nano <filename>`. Exit by pressing *control-X*.
|
running command `nano <filename>`. Exit by pressing *Ctrl-X*.
|
||||||
|
|
||||||
* **[Vim](https://www.vim.org/)**: A very powerful editor that can take a while
|
* **[Vim](https://www.vim.org/)**: A very powerful editor that can take a while
|
||||||
to learn. Launch by running `vim <filename>`. Quit Vim by pressing *escape*,
|
to learn. Launch by running `vim <filename>`. Quit Vim by pressing *Esc*,
|
||||||
typing `:q`, and then pressing *return*. Vim comes with a program to learn it
|
typing `:q`, and then pressing *Enter*. Vim comes with a program to learn it
|
||||||
called `vimtutor` (just run that command to start it).
|
called `vimtutor` (just run that command to start it).
|
||||||
|
|
||||||
Other options include:
|
Other options include:
|
||||||
|
|||||||
@@ -721,7 +721,7 @@ and is enabled by default in that case. To disable it, set
|
|||||||
- Suppressed notifications when quoting a message mentioning yourself.
|
- Suppressed notifications when quoting a message mentioning yourself.
|
||||||
- Message editing now has the compose widgets for emoji, video calls, etc.
|
- Message editing now has the compose widgets for emoji, video calls, etc.
|
||||||
- Message editing now has a Markdown preview feature just like compose.
|
- Message editing now has a Markdown preview feature just like compose.
|
||||||
- Message editing now uses same "enter-sends" behavior as compose.
|
- Message editing now uses same "Enter-sends" behavior as compose.
|
||||||
- Organization administrators can now edit users' custom profile fields.
|
- Organization administrators can now edit users' custom profile fields.
|
||||||
- Optimized performance of data import from Slack, HipChat, etc.
|
- Optimized performance of data import from Slack, HipChat, etc.
|
||||||
- Improved "new user" emails to clearly indicator login details.
|
- Improved "new user" emails to clearly indicator login details.
|
||||||
@@ -828,7 +828,7 @@ Zulip installations; it has minimal changes for existing servers.
|
|||||||
#### Full feature changelog
|
#### Full feature changelog
|
||||||
- Added an organization setting for message deletion time limits.
|
- Added an organization setting for message deletion time limits.
|
||||||
- Added an organization setting to control who can edit topics.
|
- Added an organization setting to control who can edit topics.
|
||||||
- Added ctrl+K keyboard shortcut for getting to search (same as /, but
|
- Added Ctrl+K keyboard shortcut for getting to search (same as /, but
|
||||||
works even when you're inside compose).
|
works even when you're inside compose).
|
||||||
- Renamed the hotkey for starring a message to Ctrl+S.
|
- Renamed the hotkey for starring a message to Ctrl+S.
|
||||||
- Added the new `SOCIAL_AUTH_SUBDOMAIN` setting, which all servers using
|
- Added the new `SOCIAL_AUTH_SUBDOMAIN` setting, which all servers using
|
||||||
@@ -970,7 +970,7 @@ Zulip installations; it has minimal changes for existing servers.
|
|||||||
- Added support for uploading files in the message-edit UI.
|
- Added support for uploading files in the message-edit UI.
|
||||||
- Redesigned the compose are for private messages to use pretty pills
|
- Redesigned the compose are for private messages to use pretty pills
|
||||||
rather than raw email addresses to display recipients.
|
rather than raw email addresses to display recipients.
|
||||||
- Added new ctrl+B, ctrl+I, ctrl+L compose shortcuts for inserting
|
- Added new Ctrl+B, Ctrl+I, Ctrl+L compose shortcuts for inserting
|
||||||
common syntax.
|
common syntax.
|
||||||
- Added warning when linking to a private stream via typeahead.
|
- Added warning when linking to a private stream via typeahead.
|
||||||
- Added support for automatically-numbered Markdown lists.
|
- Added support for automatically-numbered Markdown lists.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ slow/expensive/complex features like querying the Twitter API to
|
|||||||
render tweets nicely). The frontend implementation is in JavaScript,
|
render tweets nicely). The frontend implementation is in JavaScript,
|
||||||
based on [marked.js](https://github.com/chjj/marked)
|
based on [marked.js](https://github.com/chjj/marked)
|
||||||
(`static/js/echo.js`), and is used to preview and locally echo
|
(`static/js/echo.js`), and is used to preview and locally echo
|
||||||
messages the moment the sender hits enter, without waiting for round
|
messages the moment the sender hits Enter, without waiting for round
|
||||||
trip from the server. Those frontend renderings are only shown to the
|
trip from the server. Those frontend renderings are only shown to the
|
||||||
sender of a message, and they are (ideally) identical to the backend
|
sender of a message, and they are (ideally) identical to the backend
|
||||||
rendering.
|
rendering.
|
||||||
@@ -71,7 +71,7 @@ If you're going to manually test some changes in the frontend Markdown
|
|||||||
implementation, the easiest way to do this is as follows:
|
implementation, the easiest way to do this is as follows:
|
||||||
|
|
||||||
1. Login to your development server.
|
1. Login to your development server.
|
||||||
2. Stop your Zulip server with ctrl-C, leaving the browser open.
|
2. Stop your Zulip server with Ctrl-C, leaving the browser open.
|
||||||
3. Compose and send the messages you'd like to test. They will be
|
3. Compose and send the messages you'd like to test. They will be
|
||||||
locally echoed using the frontend rendering.
|
locally echoed using the frontend rendering.
|
||||||
|
|
||||||
|
|||||||
@@ -249,11 +249,11 @@ populated and where the focus is placed.
|
|||||||
should now be sending to a stream.)
|
should now be sending to a stream.)
|
||||||
|
|
||||||
- Click to send
|
- Click to send
|
||||||
- Turn off enter-to-send.
|
- Turn off Enter-to-send.
|
||||||
- Send a two-paragraph message using tab and enter.
|
- Send a two-paragraph message using Tab and Enter.
|
||||||
- Send a two-paragraph message using control-enter or command-enter.
|
- Send a two-paragraph message using Ctrl-Enter or Cmd-Enter.
|
||||||
- Turn on enter-to-send.
|
- Turn on Enter-to-send.
|
||||||
- Hit enter to send.
|
- Hit Enter to send.
|
||||||
|
|
||||||
### Popover menus ###
|
### Popover menus ###
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ casper.then(function () {
|
|||||||
casper.waitUntilVisible("#private_message_recipient", function () {
|
casper.waitUntilVisible("#private_message_recipient", function () {
|
||||||
common.pm_recipient.expect("cordelia@zulip.com");
|
common.pm_recipient.expect("cordelia@zulip.com");
|
||||||
|
|
||||||
common.keypress(27); //escape
|
common.keypress(27); //Esc
|
||||||
casper.page.sendEvent("keypress", "k");
|
casper.page.sendEvent("keypress", "k");
|
||||||
casper.page.sendEvent("keypress", "r");
|
casper.page.sendEvent("keypress", "r");
|
||||||
});
|
});
|
||||||
@@ -165,7 +165,7 @@ casper.then(function () {
|
|||||||
// Make sure multiple PM recipients display properly.
|
// Make sure multiple PM recipients display properly.
|
||||||
var recipients = ["cordelia@zulip.com", "othello@zulip.com"];
|
var recipients = ["cordelia@zulip.com", "othello@zulip.com"];
|
||||||
casper.then(function () {
|
casper.then(function () {
|
||||||
common.keypress(27); // escape to dismiss compose box
|
common.keypress(27); // Esc to dismiss compose box
|
||||||
});
|
});
|
||||||
casper.waitWhileVisible(".message_comp");
|
casper.waitWhileVisible(".message_comp");
|
||||||
common.then_send_message("private", {
|
common.then_send_message("private", {
|
||||||
@@ -175,7 +175,7 @@ common.then_send_message("private", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
casper.then(function () {
|
casper.then(function () {
|
||||||
common.keypress(27); // escape to dismiss compose box
|
common.keypress(27); // Esc to dismiss compose box
|
||||||
});
|
});
|
||||||
casper.then(function () {
|
casper.then(function () {
|
||||||
common.un_narrow();
|
common.un_narrow();
|
||||||
|
|||||||
@@ -488,8 +488,8 @@ run_test("markdown_shortcuts", () => {
|
|||||||
range_length = selected_word.length;
|
range_length = selected_word.length;
|
||||||
|
|
||||||
// Test bold:
|
// Test bold:
|
||||||
// Mac env = cmd+b
|
// Mac env = Cmd+b
|
||||||
// Windows/Linux = ctrl+b
|
// Windows/Linux = Ctrl+b
|
||||||
event.keyCode = 66;
|
event.keyCode = 66;
|
||||||
event.ctrlKey = isCtrl;
|
event.ctrlKey = isCtrl;
|
||||||
event.metaKey = isCmd;
|
event.metaKey = isCmd;
|
||||||
@@ -503,8 +503,8 @@ run_test("markdown_shortcuts", () => {
|
|||||||
assert.equal("****Any **text**.", $("#compose-textarea").val());
|
assert.equal("****Any **text**.", $("#compose-textarea").val());
|
||||||
|
|
||||||
// Test italic:
|
// Test italic:
|
||||||
// Mac = cmd+i
|
// Mac = Cmd+I
|
||||||
// Windows/Linux = ctrl+i
|
// Windows/Linux = Ctrl+I
|
||||||
$("#compose-textarea").val(input_text);
|
$("#compose-textarea").val(input_text);
|
||||||
range_start = compose_value.search(selected_word);
|
range_start = compose_value.search(selected_word);
|
||||||
range_length = selected_word.length;
|
range_length = selected_word.length;
|
||||||
@@ -520,8 +520,8 @@ run_test("markdown_shortcuts", () => {
|
|||||||
assert.equal("**Any *text*.", $("#compose-textarea").val());
|
assert.equal("**Any *text*.", $("#compose-textarea").val());
|
||||||
|
|
||||||
// Test link insertion:
|
// Test link insertion:
|
||||||
// Mac = cmd+shift+l
|
// Mac = Cmd+Shift+L
|
||||||
// Windows/Linux = ctrl+shift+l
|
// Windows/Linux = Ctrl+Shift+L
|
||||||
$("#compose-textarea").val(input_text);
|
$("#compose-textarea").val(input_text);
|
||||||
range_start = compose_value.search(selected_word);
|
range_start = compose_value.search(selected_word);
|
||||||
range_length = selected_word.length;
|
range_length = selected_word.length;
|
||||||
@@ -535,7 +535,7 @@ run_test("markdown_shortcuts", () => {
|
|||||||
compose.handle_keydown(event, $("#compose-textarea"));
|
compose.handle_keydown(event, $("#compose-textarea"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function cross tests the cmd/ctrl + Markdown shortcuts in
|
// This function cross tests the Cmd/Ctrl + Markdown shortcuts in
|
||||||
// Mac and Linux/Windows environments. So in short, this tests
|
// Mac and Linux/Windows environments. So in short, this tests
|
||||||
// that e.g. Cmd+B should be ignored on Linux/Windows and Ctrl+B
|
// that e.g. Cmd+B should be ignored on Linux/Windows and Ctrl+B
|
||||||
// should be ignored on Mac.
|
// should be ignored on Mac.
|
||||||
@@ -569,7 +569,7 @@ run_test("markdown_shortcuts", () => {
|
|||||||
|
|
||||||
// Default (Linux/Windows) userAgent tests:
|
// Default (Linux/Windows) userAgent tests:
|
||||||
test_i_typed(false, false);
|
test_i_typed(false, false);
|
||||||
// Check all the ctrl + Markdown shortcuts work correctly
|
// Check all the Ctrl + Markdown shortcuts work correctly
|
||||||
all_markdown_test(true, false);
|
all_markdown_test(true, false);
|
||||||
// The Cmd + Markdown shortcuts should do nothing on Linux/Windows
|
// The Cmd + Markdown shortcuts should do nothing on Linux/Windows
|
||||||
os_specific_markdown_test(false, true);
|
os_specific_markdown_test(false, true);
|
||||||
@@ -579,7 +579,7 @@ run_test("markdown_shortcuts", () => {
|
|||||||
|
|
||||||
// Mac userAgent tests:
|
// Mac userAgent tests:
|
||||||
test_i_typed(false, false);
|
test_i_typed(false, false);
|
||||||
// The ctrl + Markdown shortcuts should do nothing on mac
|
// The Ctrl + Markdown shortcuts should do nothing on mac
|
||||||
os_specific_markdown_test(true, false);
|
os_specific_markdown_test(true, false);
|
||||||
// Check all the Cmd + Markdown shortcuts work correctly
|
// Check all the Cmd + Markdown shortcuts work correctly
|
||||||
all_markdown_test(false, true);
|
all_markdown_test(false, true);
|
||||||
|
|||||||
@@ -1002,7 +1002,7 @@ run_test("initialize", () => {
|
|||||||
event.target.id = "some_non_existing_id";
|
event.target.id = "some_non_existing_id";
|
||||||
$("form#send_message_form").trigger(event);
|
$("form#send_message_form").trigger(event);
|
||||||
|
|
||||||
// Setup jquery functions used in compose_textarea enter
|
// Set up jquery functions used in compose_textarea Enter
|
||||||
// handler.
|
// handler.
|
||||||
let range_length = 0;
|
let range_length = 0;
|
||||||
$("#compose-textarea").range = function () {
|
$("#compose-textarea").range = function () {
|
||||||
|
|||||||
@@ -123,47 +123,47 @@ run_test("mappings", () => {
|
|||||||
assert.equal(map_press(47).name, "search"); // slash
|
assert.equal(map_press(47).name, "search"); // slash
|
||||||
assert.equal(map_press(106).name, "vim_down"); // j
|
assert.equal(map_press(106).name, "vim_down"); // j
|
||||||
|
|
||||||
assert.equal(map_down(219, false, true).name, "escape"); // ctrl + [
|
assert.equal(map_down(219, false, true).name, "escape"); // Ctrl + [
|
||||||
assert.equal(map_down(67, false, true).name, "copy_with_c"); // ctrl + c
|
assert.equal(map_down(67, false, true).name, "copy_with_c"); // Ctrl + C
|
||||||
assert.equal(map_down(75, false, true).name, "search_with_k"); // ctrl + k
|
assert.equal(map_down(75, false, true).name, "search_with_k"); // Ctrl + K
|
||||||
assert.equal(map_down(83, false, true).name, "star_message"); // ctrl + s
|
assert.equal(map_down(83, false, true).name, "star_message"); // Ctrl + S
|
||||||
assert.equal(map_down(190, false, true).name, "narrow_to_compose_target"); // ctrl + .
|
assert.equal(map_down(190, false, true).name, "narrow_to_compose_target"); // Ctrl + .
|
||||||
|
|
||||||
// More negative tests.
|
// More negative tests.
|
||||||
assert.equal(map_down(47), undefined);
|
assert.equal(map_down(47), undefined);
|
||||||
assert.equal(map_press(27), undefined);
|
assert.equal(map_press(27), undefined);
|
||||||
assert.equal(map_down(27, true), undefined);
|
assert.equal(map_down(27, true), undefined);
|
||||||
assert.equal(map_down(86, false, true), undefined); // ctrl + v
|
assert.equal(map_down(86, false, true), undefined); // Ctrl + V
|
||||||
assert.equal(map_down(90, false, true), undefined); // ctrl + z
|
assert.equal(map_down(90, false, true), undefined); // Ctrl + Z
|
||||||
assert.equal(map_down(84, false, true), undefined); // ctrl + t
|
assert.equal(map_down(84, false, true), undefined); // Ctrl + T
|
||||||
assert.equal(map_down(82, false, true), undefined); // ctrl + r
|
assert.equal(map_down(82, false, true), undefined); // Ctrl + R
|
||||||
assert.equal(map_down(79, false, true), undefined); // ctrl + o
|
assert.equal(map_down(79, false, true), undefined); // Ctrl + O
|
||||||
assert.equal(map_down(80, false, true), undefined); // ctrl + p
|
assert.equal(map_down(80, false, true), undefined); // Ctrl + P
|
||||||
assert.equal(map_down(65, false, true), undefined); // ctrl + a
|
assert.equal(map_down(65, false, true), undefined); // Ctrl + A
|
||||||
assert.equal(map_down(70, false, true), undefined); // ctrl + f
|
assert.equal(map_down(70, false, true), undefined); // Ctrl + F
|
||||||
assert.equal(map_down(72, false, true), undefined); // ctrl + h
|
assert.equal(map_down(72, false, true), undefined); // Ctrl + H
|
||||||
assert.equal(map_down(88, false, true), undefined); // ctrl + x
|
assert.equal(map_down(88, false, true), undefined); // Ctrl + X
|
||||||
assert.equal(map_down(78, false, true), undefined); // ctrl + n
|
assert.equal(map_down(78, false, true), undefined); // Ctrl + N
|
||||||
assert.equal(map_down(77, false, true), undefined); // ctrl + m
|
assert.equal(map_down(77, false, true), undefined); // Ctrl + M
|
||||||
assert.equal(map_down(67, false, false, true), undefined); // cmd + c
|
assert.equal(map_down(67, false, false, true), undefined); // Cmd + C
|
||||||
assert.equal(map_down(75, false, false, true), undefined); // cmd + k
|
assert.equal(map_down(75, false, false, true), undefined); // Cmd + K
|
||||||
assert.equal(map_down(83, false, false, true), undefined); // cmd + s
|
assert.equal(map_down(83, false, false, true), undefined); // Cmd + S
|
||||||
assert.equal(map_down(75, true, true), undefined); // shift + ctrl + k
|
assert.equal(map_down(75, true, true), undefined); // Shift + Ctrl + K
|
||||||
assert.equal(map_down(83, true, true), undefined); // shift + ctrl + s
|
assert.equal(map_down(83, true, true), undefined); // Shift + Ctrl + S
|
||||||
assert.equal(map_down(219, true, true, false), undefined); // shift + ctrl + [
|
assert.equal(map_down(219, true, true, false), undefined); // Shift + Ctrl + [
|
||||||
|
|
||||||
// CMD tests for MacOS
|
// Cmd tests for MacOS
|
||||||
global.navigator.platform = "MacIntel";
|
global.navigator.platform = "MacIntel";
|
||||||
assert.equal(map_down(219, false, true, false).name, "escape"); // ctrl + [
|
assert.equal(map_down(219, false, true, false).name, "escape"); // Ctrl + [
|
||||||
assert.equal(map_down(219, false, false, true), undefined); // cmd + [
|
assert.equal(map_down(219, false, false, true), undefined); // Cmd + [
|
||||||
assert.equal(map_down(67, false, true, true).name, "copy_with_c"); // ctrl + c
|
assert.equal(map_down(67, false, true, true).name, "copy_with_c"); // Ctrl + C
|
||||||
assert.equal(map_down(67, false, true, false), undefined); // cmd + c
|
assert.equal(map_down(67, false, true, false), undefined); // Cmd + C
|
||||||
assert.equal(map_down(75, false, false, true).name, "search_with_k"); // cmd + k
|
assert.equal(map_down(75, false, false, true).name, "search_with_k"); // Cmd + K
|
||||||
assert.equal(map_down(75, false, true, false), undefined); // ctrl + k
|
assert.equal(map_down(75, false, true, false), undefined); // Ctrl + K
|
||||||
assert.equal(map_down(83, false, false, true).name, "star_message"); // cmd + s
|
assert.equal(map_down(83, false, false, true).name, "star_message"); // Cmd + S
|
||||||
assert.equal(map_down(83, false, true, false), undefined); // ctrl + s
|
assert.equal(map_down(83, false, true, false), undefined); // Ctrl + S
|
||||||
assert.equal(map_down(190, false, false, true).name, "narrow_to_compose_target"); // cmd + .
|
assert.equal(map_down(190, false, false, true).name, "narrow_to_compose_target"); // Cmd + .
|
||||||
assert.equal(map_down(190, false, true, false), undefined); // ctrl + .
|
assert.equal(map_down(190, false, true, false), undefined); // Ctrl + .
|
||||||
// Reset platform
|
// Reset platform
|
||||||
global.navigator.platform = "";
|
global.navigator.platform = "";
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ run_test("comma", () => {
|
|||||||
assert.deepEqual(widget.items(), [items.blue, items.red, items.yellow]);
|
assert.deepEqual(widget.items(), [items.blue, items.red, items.yellow]);
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("enter key with text", () => {
|
run_test("Enter key with text", () => {
|
||||||
const info = set_up();
|
const info = set_up();
|
||||||
const config = info.config;
|
const config = info.config;
|
||||||
const items = info.items;
|
const items = info.items;
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ run_test("initialize", () => {
|
|||||||
_setup("ver");
|
_setup("ver");
|
||||||
search.is_using_input_method = true;
|
search.is_using_input_method = true;
|
||||||
searchbox_form.trigger(ev);
|
searchbox_form.trigger(ev);
|
||||||
// No change on enter keyup event when using input tool
|
// No change on Enter keyup event when using input tool
|
||||||
assert(!is_blurred);
|
assert(!is_blurred);
|
||||||
assert(!search_button.prop("disabled"));
|
assert(!search_button.prop("disabled"));
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ run_test("initialize", () => {
|
|||||||
_setup("ver");
|
_setup("ver");
|
||||||
search.is_using_input_method = true;
|
search.is_using_input_method = true;
|
||||||
searchbox_form.trigger(ev);
|
searchbox_form.trigger(ev);
|
||||||
// No change on enter keyup event when using input tool
|
// No change on Enter keyup event when using input tool
|
||||||
assert(!is_blurred);
|
assert(!is_blurred);
|
||||||
assert(!search_button.prop("disabled"));
|
assert(!search_button.prop("disabled"));
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ exports.set_up_alert_words = function () {
|
|||||||
|
|
||||||
$("#create_alert_word_form").on("keypress", "#create_alert_word_name", (event) => {
|
$("#create_alert_word_form").on("keypress", "#create_alert_word_name", (event) => {
|
||||||
const key = event.which;
|
const key = event.which;
|
||||||
// Handle enter (13) as "add".
|
// Handle Enter (13) as "add".
|
||||||
if (key === 13) {
|
if (key === 13) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const util = require("./util");
|
|||||||
function convert_enter_to_click(e) {
|
function convert_enter_to_click(e) {
|
||||||
const key = e.which;
|
const key = e.which;
|
||||||
if (key === 13) {
|
if (key === 13) {
|
||||||
// enter
|
// Enter
|
||||||
$(e.currentTarget).trigger("click");
|
$(e.currentTarget).trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,7 +682,7 @@ exports.initialize = function () {
|
|||||||
|
|
||||||
// Don't let clicks in the compose area count as
|
// Don't let clicks in the compose area count as
|
||||||
// "unfocusing" our compose -- in other words, e.g.
|
// "unfocusing" our compose -- in other words, e.g.
|
||||||
// clicking "Press enter to send" should not
|
// clicking "Press Enter to send" should not
|
||||||
// trigger the composebox-closing code above.
|
// trigger the composebox-closing code above.
|
||||||
// But do allow our formatting link.
|
// But do allow our formatting link.
|
||||||
if (!$(e.target).is("a")) {
|
if (!$(e.target).is("a")) {
|
||||||
|
|||||||
@@ -731,7 +731,7 @@ exports.handle_keydown = function (event, textarea) {
|
|||||||
const isItalic = code === 73 && !event.shiftKey;
|
const isItalic = code === 73 && !event.shiftKey;
|
||||||
const isLink = code === 76 && event.shiftKey;
|
const isLink = code === 76 && event.shiftKey;
|
||||||
|
|
||||||
// detect command and ctrl key
|
// detect Cmd and Ctrl key
|
||||||
const isCmdOrCtrl = common.has_mac_keyboard() ? event.metaKey : event.ctrlKey;
|
const isCmdOrCtrl = common.has_mac_keyboard() ? event.metaKey : event.ctrlKey;
|
||||||
|
|
||||||
if ((isBold || isItalic || isLink) && isCmdOrCtrl) {
|
if ((isBold || isItalic || isLink) && isCmdOrCtrl) {
|
||||||
@@ -744,21 +744,21 @@ exports.handle_keydown = function (event, textarea) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isBold) {
|
if (isBold) {
|
||||||
// ctrl + b: Convert selected text to bold text
|
// Ctrl + B: Convert selected text to bold text
|
||||||
wrap_text_with_markdown("**", "**");
|
wrap_text_with_markdown("**", "**");
|
||||||
if (!range.length) {
|
if (!range.length) {
|
||||||
textarea.caret(textarea.caret() - 2);
|
textarea.caret(textarea.caret() - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isItalic) {
|
if (isItalic) {
|
||||||
// ctrl + i: Convert selected text to italic text
|
// Ctrl + I: Convert selected text to italic text
|
||||||
wrap_text_with_markdown("*", "*");
|
wrap_text_with_markdown("*", "*");
|
||||||
if (!range.length) {
|
if (!range.length) {
|
||||||
textarea.caret(textarea.caret() - 1);
|
textarea.caret(textarea.caret() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isLink) {
|
if (isLink) {
|
||||||
// ctrl + l: Insert a link to selected text
|
// Ctrl + L: Insert a link to selected text
|
||||||
wrap_text_with_markdown("[", "](url)");
|
wrap_text_with_markdown("[", "](url)");
|
||||||
const position = textarea.caret();
|
const position = textarea.caret();
|
||||||
const txt = document.getElementById(textarea[0].id);
|
const txt = document.getElementById(textarea[0].id);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ function get_topic_matcher(query) {
|
|||||||
// nextFocus is set on a keydown event to indicate where we should focus on keyup.
|
// nextFocus is set on a keydown event to indicate where we should focus on keyup.
|
||||||
// We can't focus at the time of keydown because we need to wait for typeahead.
|
// We can't focus at the time of keydown because we need to wait for typeahead.
|
||||||
// And we can't compute where to focus at the time of keyup because only the keydown
|
// And we can't compute where to focus at the time of keyup because only the keydown
|
||||||
// has reliable information about whether it was a tab or a shift+tab.
|
// has reliable information about whether it was a Tab or a Shift+Tab.
|
||||||
let nextFocus = false;
|
let nextFocus = false;
|
||||||
|
|
||||||
exports.should_enter_send = function (e) {
|
exports.should_enter_send = function (e) {
|
||||||
@@ -129,33 +129,33 @@ exports.should_enter_send = function (e) {
|
|||||||
this_enter_sends = !has_modifier_key;
|
this_enter_sends = !has_modifier_key;
|
||||||
} else {
|
} else {
|
||||||
// If enter_sends is not enabled, just hitting
|
// If enter_sends is not enabled, just hitting
|
||||||
// enter should add a newline, but with a
|
// Snter should add a newline, but with a
|
||||||
// non-shift modifier key held down, we should
|
// non-Shift modifier key held down, we should
|
||||||
// send. With shift, we shouldn't, because
|
// send. With Shift, we shouldn't, because
|
||||||
// shift+enter to get a newline is a common
|
// Shift+Enter to get a newline is a common
|
||||||
// keyboard habit for folks for dealing with other
|
// keyboard habit for folks for dealing with other
|
||||||
// chat products where enter-always-sends.
|
// chat products where Enter-always-sends.
|
||||||
this_enter_sends = has_non_shift_modifier_key;
|
this_enter_sends = has_non_shift_modifier_key;
|
||||||
}
|
}
|
||||||
return this_enter_sends;
|
return this_enter_sends;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.handle_enter = function (textarea, e) {
|
exports.handle_enter = function (textarea, e) {
|
||||||
// Used only if enter doesn't send.
|
// Used only if Enter doesn't send.
|
||||||
|
|
||||||
// Since this enter doesn't send, we just want to do
|
// Since this Enter doesn't send, we just want to do
|
||||||
// the browser's default behavior for the "enter" key.
|
// the browser's default behavior for the "Enter" key.
|
||||||
// Letting the browser handle it works great if the
|
// Letting the browser handle it works great if the
|
||||||
// key actually pressed was enter or shift-enter.
|
// key actually pressed was Enter or Shift-Enter.
|
||||||
|
|
||||||
// But the default browser behavior for ctrl/alt/meta
|
// But the default browser behavior for Ctrl/Alt/Meta
|
||||||
// + enter is to do nothing, so we need to emulate
|
// + Enter is to do nothing, so we need to emulate
|
||||||
// the browser behavior for "enter" in those cases.
|
// the browser behavior for "Enter" in those cases.
|
||||||
//
|
//
|
||||||
// We do this using caret and range from jquery-caret.
|
// We do this using caret and range from jquery-caret.
|
||||||
const has_non_shift_modifier_key = e.ctrlKey || e.metaKey || e.altKey;
|
const has_non_shift_modifier_key = e.ctrlKey || e.metaKey || e.altKey;
|
||||||
if (has_non_shift_modifier_key) {
|
if (has_non_shift_modifier_key) {
|
||||||
// To properly emulate browser "enter", if the
|
// To properly emulate browser "Enter", if the
|
||||||
// user had selected something in the textarea,
|
// user had selected something in the textarea,
|
||||||
// we need those characters to be cleared.
|
// we need those characters to be cleared.
|
||||||
const range = textarea.range();
|
const range = textarea.range();
|
||||||
@@ -177,7 +177,7 @@ function handle_keydown(e) {
|
|||||||
const code = e.keyCode || e.which;
|
const code = e.keyCode || e.which;
|
||||||
|
|
||||||
if (code === 13 || (code === 9 && !e.shiftKey)) {
|
if (code === 13 || (code === 9 && !e.shiftKey)) {
|
||||||
// Enter key or tab key
|
// Enter key or Tab key
|
||||||
let target_sel;
|
let target_sel;
|
||||||
|
|
||||||
if (e.target.id) {
|
if (e.target.id) {
|
||||||
@@ -190,12 +190,12 @@ function handle_keydown(e) {
|
|||||||
const on_compose = target_sel === "#compose-textarea";
|
const on_compose = target_sel === "#compose-textarea";
|
||||||
|
|
||||||
if (on_stream || on_topic || on_pm) {
|
if (on_stream || on_topic || on_pm) {
|
||||||
// For enter, prevent the form from submitting
|
// For Enter, prevent the form from submitting
|
||||||
// For tab, prevent the focus from changing again
|
// For Tab, prevent the focus from changing again
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the compose_textarea box, preventDefault() for tab but not for enter
|
// In the compose_textarea box, preventDefault() for Tab but not for Enter
|
||||||
if (on_compose && code !== 13) {
|
if (on_compose && code !== 13) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
@@ -230,8 +230,8 @@ function handle_keydown(e) {
|
|||||||
) {
|
) {
|
||||||
// If no typeaheads are shown and the user is tabbing from the message content box,
|
// If no typeaheads are shown and the user is tabbing from the message content box,
|
||||||
// then there's no need to wait and we can change the focus right away.
|
// then there's no need to wait and we can change the focus right away.
|
||||||
// Without this code to change the focus right away, if the user presses enter
|
// Without this code to change the focus right away, if the user presses Enter
|
||||||
// before they fully release the tab key, the tab will be lost. Note that we don't
|
// before they fully release the Tab key, the Tab will be lost. Note that we don't
|
||||||
// want to change focus right away in the private_message_recipient box since it
|
// want to change focus right away in the private_message_recipient box since it
|
||||||
// takes the typeaheads a little time to open after the user finishes typing, which
|
// takes the typeaheads a little time to open after the user finishes typing, which
|
||||||
// can lead to the focus moving without the autocomplete having a chance to happen.
|
// can lead to the focus moving without the autocomplete having a chance to happen.
|
||||||
@@ -258,7 +258,7 @@ function handle_keydown(e) {
|
|||||||
function handle_keyup(e) {
|
function handle_keyup(e) {
|
||||||
const code = e.keyCode || e.which;
|
const code = e.keyCode || e.which;
|
||||||
if (code === 13 || (code === 9 && !e.shiftKey)) {
|
if (code === 13 || (code === 9 && !e.shiftKey)) {
|
||||||
// Enter key or tab key
|
// Enter key or Tab key
|
||||||
if (nextFocus) {
|
if (nextFocus) {
|
||||||
$(nextFocus).trigger("focus");
|
$(nextFocus).trigger("focus");
|
||||||
nextFocus = false;
|
nextFocus = false;
|
||||||
@@ -854,7 +854,7 @@ exports.content_typeahead_selected = function (item, event) {
|
|||||||
}
|
}
|
||||||
beginning += "#**" + item.name;
|
beginning += "#**" + item.name;
|
||||||
if (event && event.key === ">") {
|
if (event && event.key === ">") {
|
||||||
// Normally, one accepts typeahead with `tab` or `enter`, but when completing
|
// Normally, one accepts typeahead with `Tab` or `Enter`, but when completing
|
||||||
// stream typeahead, we allow `>`, the delimiter for stream+topic mentions,
|
// stream typeahead, we allow `>`, the delimiter for stream+topic mentions,
|
||||||
// as a completion that automatically sets up stream+topic typeahead for you.
|
// as a completion that automatically sets up stream+topic typeahead for you.
|
||||||
beginning += ">";
|
beginning += ">";
|
||||||
@@ -1034,7 +1034,7 @@ exports.initialize_compose_typeahead = function (selector) {
|
|||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
updater: exports.content_typeahead_selected,
|
updater: exports.content_typeahead_selected,
|
||||||
stopAdvance: true, // Do not advance to the next field on a tab or enter
|
stopAdvance: true, // Do not advance to the next field on a Tab or Enter
|
||||||
completions,
|
completions,
|
||||||
automated: exports.compose_automated_selection,
|
automated: exports.compose_automated_selection,
|
||||||
trigger_selection: exports.compose_trigger_selection,
|
trigger_selection: exports.compose_trigger_selection,
|
||||||
@@ -1144,7 +1144,7 @@ exports.initialize = function () {
|
|||||||
compose_pm_pill.set_from_typeahead(item);
|
compose_pm_pill.set_from_typeahead(item);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stopAdvance: true, // Do not advance to the next field on a tab or enter
|
stopAdvance: true, // Do not advance to the next field on a Tab or Enter
|
||||||
});
|
});
|
||||||
|
|
||||||
exports.initialize_compose_typeahead("#compose-textarea");
|
exports.initialize_compose_typeahead("#compose-textarea");
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ function remove_div(div, ranges, selection) {
|
|||||||
|
|
||||||
exports.copy_handler = function () {
|
exports.copy_handler = function () {
|
||||||
// This is the main handler for copying message content via
|
// This is the main handler for copying message content via
|
||||||
// `ctrl+C` in Zulip (note that this is totally independent of the
|
// `Ctrl+C` in Zulip (note that this is totally independent of the
|
||||||
// "select region" copy behavior on Linux; that is handled
|
// "select region" copy behavior on Linux; that is handled
|
||||||
// entirely by the browser, our HTML layout, and our use of the
|
// entirely by the browser, our HTML layout, and our use of the
|
||||||
// no-select/auto-select CSS classes). We put considerable effort
|
// no-select/auto-select CSS classes). We put considerable effort
|
||||||
@@ -134,7 +134,7 @@ exports.copy_handler = function () {
|
|||||||
//
|
//
|
||||||
// * If the selection is contained within a single message, we
|
// * If the selection is contained within a single message, we
|
||||||
// want to just copy the portion that was selected, which we
|
// want to just copy the portion that was selected, which we
|
||||||
// implement by letting the browser handle the ctrl+C event.
|
// implement by letting the browser handle the Ctrl+C event.
|
||||||
//
|
//
|
||||||
// * Otherwise, we want to copy the bodies of all messages that
|
// * Otherwise, we want to copy the bodies of all messages that
|
||||||
// were partially covered by the selection.
|
// were partially covered by the selection.
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ exports.drafts_handle_events = function (e, event_key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const focused_draft_id = row_with_focus().data("draft-id");
|
const focused_draft_id = row_with_focus().data("draft-id");
|
||||||
// Allows user to delete drafts with backspace
|
// Allows user to delete drafts with Backspace
|
||||||
if (event_key === "backspace" || event_key === "delete") {
|
if (event_key === "backspace" || event_key === "delete") {
|
||||||
if (focused_draft_id !== undefined) {
|
if (focused_draft_id !== undefined) {
|
||||||
const draft_row = row_with_focus();
|
const draft_row = row_with_focus();
|
||||||
@@ -498,7 +498,7 @@ exports.drafts_handle_events = function (e, event_key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This handles when pressing enter while looking at drafts.
|
// This handles when pressing Enter while looking at drafts.
|
||||||
// It restores draft that is focused.
|
// It restores draft that is focused.
|
||||||
if (event_key === "enter") {
|
if (event_key === "enter") {
|
||||||
if (document.activeElement.parentElement.hasAttribute("data-draft-id")) {
|
if (document.activeElement.parentElement.hasAttribute("data-draft-id")) {
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ function is_composition(emoji) {
|
|||||||
|
|
||||||
function process_enter_while_filtering(e) {
|
function process_enter_while_filtering(e) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
// enter key
|
// Enter key
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const first_emoji = get_rendered_emoji(0, 0);
|
const first_emoji = get_rendered_emoji(0, 0);
|
||||||
if (first_emoji) {
|
if (first_emoji) {
|
||||||
@@ -411,7 +411,7 @@ exports.navigate = function (event_name, e) {
|
|||||||
|
|
||||||
// If search is active and results are empty then return immediately.
|
// If search is active and results are empty then return immediately.
|
||||||
if (search_is_active === true && search_results.length === 0) {
|
if (search_is_active === true && search_results.length === 0) {
|
||||||
// We don't want to prevent default for keys like backspace and space.
|
// We don't want to prevent default for keys like Backspace and space.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +513,7 @@ function process_keypress(e) {
|
|||||||
if (!is_filter_focused && pressed_key !== 58) {
|
if (!is_filter_focused && pressed_key !== 58) {
|
||||||
// ':' => 58, is a hotkey for toggling reactions popover.
|
// ':' => 58, is a hotkey for toggling reactions popover.
|
||||||
if ((pressed_key >= 32 && pressed_key <= 126) || pressed_key === 8) {
|
if ((pressed_key >= 32 && pressed_key <= 126) || pressed_key === 8) {
|
||||||
// Handle only printable characters or backspace.
|
// Handle only printable characters or Backspace.
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
@@ -522,7 +522,7 @@ function process_keypress(e) {
|
|||||||
let new_query = "";
|
let new_query = "";
|
||||||
|
|
||||||
if (pressed_key === 8) {
|
if (pressed_key === 8) {
|
||||||
// Handles backspace.
|
// Handles Backspace.
|
||||||
new_query = old_query.slice(0, -1);
|
new_query = old_query.slice(0, -1);
|
||||||
} else {
|
} else {
|
||||||
// Handles any printable character.
|
// Handles any printable character.
|
||||||
@@ -573,10 +573,10 @@ function register_popover_events(popover) {
|
|||||||
$(".emoji-popover-filter").on("keydown", process_enter_while_filtering);
|
$(".emoji-popover-filter").on("keydown", process_enter_while_filtering);
|
||||||
$(".emoji-popover").on("keypress", process_keypress);
|
$(".emoji-popover").on("keypress", process_keypress);
|
||||||
$(".emoji-popover").on("keydown", (e) => {
|
$(".emoji-popover").on("keydown", (e) => {
|
||||||
// Because of cross-browser issues we need to handle backspace
|
// Because of cross-browser issues we need to handle Backspace
|
||||||
// key separately. Firefox fires `keypress` event for backspace
|
// key separately. Firefox fires `keypress` event for Backspace
|
||||||
// key but chrome doesn't so we need to trigger the logic for
|
// key but chrome doesn't so we need to trigger the logic for
|
||||||
// handling backspace in `keydown` event which is fired by both.
|
// handling Backspace in `keydown` event which is fired by both.
|
||||||
if (e.which === 8) {
|
if (e.which === 8) {
|
||||||
process_keypress(e);
|
process_keypress(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ const menu_dropdown_hotkeys = ["down_arrow", "up_arrow", "vim_up", "vim_down", "
|
|||||||
|
|
||||||
// The `message_view_only` property is a convenient and performant way
|
// The `message_view_only` property is a convenient and performant way
|
||||||
// to express a common case of which hotkeys do something in which
|
// to express a common case of which hotkeys do something in which
|
||||||
// views. It is set for hotkeys (like `Ctrl + s`) that only have an effect
|
// views. It is set for hotkeys (like `Ctrl + S`) that only have an effect
|
||||||
// in the main message view with a selected message.
|
// in the main message view with a selected message.
|
||||||
// `message_view_only` hotkeys, as a group, are not processed if any
|
// `message_view_only` hotkeys, as a group, are not processed if any
|
||||||
// overlays are open (e.g. settings, streams, etc.).
|
// overlays are open (e.g. settings, streams, etc.).
|
||||||
|
|
||||||
const keydown_shift_mappings = {
|
const keydown_shift_mappings = {
|
||||||
// these can be triggered by shift + key only
|
// these can be triggered by Shift + key only
|
||||||
9: {name: "shift_tab", message_view_only: false}, // tab
|
9: {name: "shift_tab", message_view_only: false}, // Tab
|
||||||
32: {name: "shift_spacebar", message_view_only: true}, // space bar
|
32: {name: "shift_spacebar", message_view_only: true}, // space bar
|
||||||
37: {name: "left_arrow", message_view_only: false}, // left arrow
|
37: {name: "left_arrow", message_view_only: false}, // left arrow
|
||||||
39: {name: "right_arrow", message_view_only: false}, // right arrow
|
39: {name: "right_arrow", message_view_only: false}, // right arrow
|
||||||
@@ -32,14 +32,14 @@ const keydown_shift_mappings = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const keydown_unshift_mappings = {
|
const keydown_unshift_mappings = {
|
||||||
// these can be triggered by key only (without shift)
|
// these can be triggered by key only (without Shift)
|
||||||
9: {name: "tab", message_view_only: false}, // tab
|
9: {name: "tab", message_view_only: false}, // Tab
|
||||||
27: {name: "escape", message_view_only: false}, // escape
|
27: {name: "escape", message_view_only: false}, // Esc
|
||||||
32: {name: "spacebar", message_view_only: true}, // space bar
|
32: {name: "spacebar", message_view_only: true}, // space bar
|
||||||
33: {name: "page_up", message_view_only: true}, // page up
|
33: {name: "page_up", message_view_only: true}, // PgUp
|
||||||
34: {name: "page_down", message_view_only: true}, // page down
|
34: {name: "page_down", message_view_only: true}, // PgDn
|
||||||
35: {name: "end", message_view_only: true}, // end
|
35: {name: "end", message_view_only: true}, // End
|
||||||
36: {name: "home", message_view_only: true}, // home
|
36: {name: "home", message_view_only: true}, // Home
|
||||||
37: {name: "left_arrow", message_view_only: false}, // left arrow
|
37: {name: "left_arrow", message_view_only: false}, // left arrow
|
||||||
39: {name: "right_arrow", message_view_only: false}, // right arrow
|
39: {name: "right_arrow", message_view_only: false}, // right arrow
|
||||||
38: {name: "up_arrow", message_view_only: false}, // up arrow
|
38: {name: "up_arrow", message_view_only: false}, // up arrow
|
||||||
@@ -53,25 +53,25 @@ const keydown_ctrl_mappings = {
|
|||||||
const keydown_cmd_or_ctrl_mappings = {
|
const keydown_cmd_or_ctrl_mappings = {
|
||||||
67: {name: "copy_with_c", message_view_only: false}, // 'C'
|
67: {name: "copy_with_c", message_view_only: false}, // 'C'
|
||||||
75: {name: "search_with_k", message_view_only: false}, // 'K'
|
75: {name: "search_with_k", message_view_only: false}, // 'K'
|
||||||
83: {name: "star_message", message_view_only: true}, // 's'
|
83: {name: "star_message", message_view_only: true}, // 'S'
|
||||||
190: {name: "narrow_to_compose_target", message_view_only: true}, // '.'
|
190: {name: "narrow_to_compose_target", message_view_only: true}, // '.'
|
||||||
};
|
};
|
||||||
|
|
||||||
const keydown_either_mappings = {
|
const keydown_either_mappings = {
|
||||||
// these can be triggered by key or shift + key
|
// these can be triggered by key or Shift + key
|
||||||
// Note that codes for letters are still case sensitive!
|
// Note that codes for letters are still case sensitive!
|
||||||
//
|
//
|
||||||
// We may want to revisit both of these. For backspace, we don't
|
// We may want to revisit both of these. For Backspace, we don't
|
||||||
// have any specific mapping behavior; we are just trying to disable
|
// have any specific mapping behavior; we are just trying to disable
|
||||||
// the normal browser features for certain OSes when we are in the
|
// the normal browser features for certain OSes when we are in the
|
||||||
// compose box, and the little bit of backspace-related code here is
|
// compose box, and the little bit of Backspace-related code here is
|
||||||
// dubious, but may apply to shift-backspace.
|
// dubious, but may apply to Shift-Backspace.
|
||||||
// For enter, there is some possibly that shift-enter is intended to
|
// For Enter, there is some possibly that Shift-Enter is intended to
|
||||||
// have special behavior for folks that are used to shift-enter behavior
|
// have special behavior for folks that are used to Shift-Enter behavior
|
||||||
// in other apps, but that's also slightly dubious.
|
// in other apps, but that's also slightly dubious.
|
||||||
8: {name: "backspace", message_view_only: true}, // backspace
|
8: {name: "backspace", message_view_only: true}, // Backspace
|
||||||
13: {name: "enter", message_view_only: false}, // enter
|
13: {name: "enter", message_view_only: false}, // Enter
|
||||||
46: {name: "delete", message_view_only: false}, // delete
|
46: {name: "delete", message_view_only: false}, // Delete
|
||||||
};
|
};
|
||||||
|
|
||||||
const keypress_mappings = {
|
const keypress_mappings = {
|
||||||
@@ -231,7 +231,7 @@ exports.process_escape_key = function (e) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user hit the escape key, cancel the current compose
|
// If the user hit the Esc key, cancel the current compose
|
||||||
compose_actions.cancel();
|
compose_actions.cancel();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ exports.process_enter_key = function (e) {
|
|||||||
|
|
||||||
if (overlays.settings_open()) {
|
if (overlays.settings_open()) {
|
||||||
// On the settings page just let the browser handle
|
// On the settings page just let the browser handle
|
||||||
// the enter key for things like submitting forms.
|
// the Enter key for things like submitting forms.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,20 +323,20 @@ exports.process_enter_key = function (e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This handles when pressing enter while looking at drafts.
|
// This handles when pressing Rnter while looking at drafts.
|
||||||
// It restores draft that is focused.
|
// It restores draft that is focused.
|
||||||
if (overlays.drafts_open()) {
|
if (overlays.drafts_open()) {
|
||||||
drafts.drafts_handle_events(e, "enter");
|
drafts.drafts_handle_events(e, "enter");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're on a button or a link and have pressed enter, let the
|
// If we're on a button or a link and have pressed Enter, let the
|
||||||
// browser handle the keypress
|
// browser handle the keypress
|
||||||
//
|
//
|
||||||
// This is subtle and here's why: Suppose you have the focus on a
|
// This is subtle and here's why: Suppose you have the focus on a
|
||||||
// stream name in your left sidebar. j and k will still move your
|
// stream name in your left sidebar. j and k will still move your
|
||||||
// cursor up and down, but Enter won't reply -- it'll just trigger
|
// cursor up and down, but Enter won't reply -- it'll just trigger
|
||||||
// the link on the sidebar! So you keep pressing enter over and
|
// the link on the sidebar! So you keep pressing Enter over and
|
||||||
// over again. Until you click somewhere or press r.
|
// over again. Until you click somewhere or press r.
|
||||||
if ($("a:focus,button:focus").length > 0) {
|
if ($("a:focus,button:focus").length > 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -353,7 +353,7 @@ exports.process_enter_key = function (e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we got this far, then we're presumably in the message
|
// If we got this far, then we're presumably in the message
|
||||||
// view, so in that case "enter" is the hotkey to respond to a message.
|
// view, so in that case "Enter" is the hotkey to respond to a message.
|
||||||
// Note that "r" has same effect, but that is handled in process_hotkey().
|
// Note that "r" has same effect, but that is handled in process_hotkey().
|
||||||
compose_actions.respond_to_message({trigger: "hotkey enter"});
|
compose_actions.respond_to_message({trigger: "hotkey enter"});
|
||||||
return true;
|
return true;
|
||||||
@@ -400,13 +400,13 @@ exports.process_shift_tab_key = function () {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift-tabbing from the edit message cancel button takes you to save.
|
// Shift-Tabbing from the edit message cancel button takes you to save.
|
||||||
if ($(".message_edit_cancel").filter(":focus").length > 0) {
|
if ($(".message_edit_cancel").filter(":focus").length > 0) {
|
||||||
$(".message_edit_save").trigger("focus");
|
$(".message_edit_save").trigger("focus");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift-tabbing from the edit message save button takes you to the content.
|
// Shift-Tabbing from the edit message save button takes you to the content.
|
||||||
const focused_message_edit_save = $(".message_edit_save").filter(":focus");
|
const focused_message_edit_save = $(".message_edit_save").filter(":focus");
|
||||||
if (focused_message_edit_save.length > 0) {
|
if (focused_message_edit_save.length > 0) {
|
||||||
focused_message_edit_save
|
focused_message_edit_save
|
||||||
@@ -416,7 +416,7 @@ exports.process_shift_tab_key = function () {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift-tabbing from emoji catalog/search results takes you back to search textbox.
|
// Shift-Tabbing from emoji catalog/search results takes you back to search textbox.
|
||||||
if (emoji_picker.reactions_popped()) {
|
if (emoji_picker.reactions_popped()) {
|
||||||
return emoji_picker.navigate("shift_tab");
|
return emoji_picker.navigate("shift_tab");
|
||||||
}
|
}
|
||||||
@@ -430,7 +430,7 @@ exports.process_shift_tab_key = function () {
|
|||||||
exports.process_hotkey = function (e, hotkey) {
|
exports.process_hotkey = function (e, hotkey) {
|
||||||
const event_name = hotkey.name;
|
const event_name = hotkey.name;
|
||||||
|
|
||||||
// This block needs to be before the `tab` handler.
|
// This block needs to be before the `Tab` handler.
|
||||||
switch (event_name) {
|
switch (event_name) {
|
||||||
case "up_arrow":
|
case "up_arrow":
|
||||||
case "down_arrow":
|
case "down_arrow":
|
||||||
@@ -524,7 +524,7 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (exports.in_content_editable_widget(e)) {
|
if (exports.in_content_editable_widget(e)) {
|
||||||
// We handle the enter key in process_enter_key().
|
// We handle the Enter key in process_enter_key().
|
||||||
// We ignore all other keys.
|
// We ignore all other keys.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -560,7 +560,7 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
// browser behavior.
|
// browser behavior.
|
||||||
if (event_name === "backspace") {
|
if (event_name === "backspace") {
|
||||||
if ($("#compose-send-button").is(":focus")) {
|
if ($("#compose-send-button").is(":focus")) {
|
||||||
// Ignore backspace; don't navigate back a page.
|
// Ignore Backspace; don't navigate back a page.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,7 +572,7 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
|
|
||||||
// Process hotkeys specially when in an input, select, textarea, or send button
|
// Process hotkeys specially when in an input, select, textarea, or send button
|
||||||
if (exports.processing_text()) {
|
if (exports.processing_text()) {
|
||||||
// Note that there is special handling for enter/escape too, but
|
// Note that there is special handling for Enter/Esc too, but
|
||||||
// we handle this in other functions.
|
// we handle this in other functions.
|
||||||
|
|
||||||
if (event_name === "left_arrow" && compose_state.focus_in_empty_compose()) {
|
if (event_name === "left_arrow" && compose_state.focus_in_empty_compose()) {
|
||||||
@@ -595,9 +595,9 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
$(":focus").caret(Infinity).animate({scrollTop: height}, "fast");
|
$(":focus").caret(Infinity).animate({scrollTop: height}, "fast");
|
||||||
return true;
|
return true;
|
||||||
} else if (event_name === "search_with_k") {
|
} else if (event_name === "search_with_k") {
|
||||||
// Do nothing; this allows one to use ctrl+k inside compose.
|
// Do nothing; this allows one to use Ctrl+K inside compose.
|
||||||
} else if (event_name === "star_message") {
|
} else if (event_name === "star_message") {
|
||||||
// Do nothing; this allows one to use ctrl+s inside compose.
|
// Do nothing; this allows one to use Ctrl+S inside compose.
|
||||||
} else {
|
} else {
|
||||||
// Let the browser handle the key normally.
|
// Let the browser handle the key normally.
|
||||||
return false;
|
return false;
|
||||||
@@ -684,7 +684,7 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
drafts.launch();
|
drafts.launch();
|
||||||
return true;
|
return true;
|
||||||
case "reply_message": // 'r': respond to message
|
case "reply_message": // 'r': respond to message
|
||||||
// Note that you can "enter" to respond to messages as well,
|
// Note that you can "Enter" to respond to messages as well,
|
||||||
// but that is handled in process_enter_key().
|
// but that is handled in process_enter_key().
|
||||||
compose_actions.respond_to_message({trigger: "hotkey"});
|
compose_actions.respond_to_message({trigger: "hotkey"});
|
||||||
return true;
|
return true;
|
||||||
@@ -790,7 +790,7 @@ exports.process_hotkey = function (e, hotkey) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* We register both a keydown and a keypress function because
|
/* We register both a keydown and a keypress function because
|
||||||
we want to intercept pgup/pgdn, escape, etc, and process them
|
we want to intercept PgUp/PgDn, Esc, etc, and process them
|
||||||
as they happen on the keyboard. However, if we processed
|
as they happen on the keyboard. However, if we processed
|
||||||
letters/numbers in keydown, we wouldn't know what the case of
|
letters/numbers in keydown, we wouldn't know what the case of
|
||||||
the letters were.
|
the letters were.
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ exports.create = function (opts) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// this will remove the last pill in the container -- by default tied
|
// this will remove the last pill in the container -- by default tied
|
||||||
// to the "backspace" key when the value of the input is empty.
|
// to the "Backspace" key when the value of the input is empty.
|
||||||
// If quiet is a truthy value, the event handler associated with the
|
// If quiet is a truthy value, the event handler associated with the
|
||||||
// pill will not be evaluated. This is useful when using clear to reset
|
// pill will not be evaluated. This is useful when using clear to reset
|
||||||
// the pills.
|
// the pills.
|
||||||
@@ -316,7 +316,7 @@ exports.create = function (opts) {
|
|||||||
const id = $pill.data("id");
|
const id = $pill.data("id");
|
||||||
funcs.removePill(id);
|
funcs.removePill(id);
|
||||||
$next.trigger("focus");
|
$next.trigger("focus");
|
||||||
// the "backspace" key in Firefox will go back a page if you do
|
// the "Backspace" key in Firefox will go back a page if you do
|
||||||
// not prevent it.
|
// not prevent it.
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,15 +187,15 @@ function handle_message_row_edit_keydown(e) {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case 13:
|
case 13:
|
||||||
if ($(e.target).hasClass("message_edit_content")) {
|
if ($(e.target).hasClass("message_edit_content")) {
|
||||||
// Pressing enter to save edits is coupled with enter to send
|
// Pressing Enter to save edits is coupled with Enter to send
|
||||||
if (composebox_typeahead.should_enter_send(e)) {
|
if (composebox_typeahead.should_enter_send(e)) {
|
||||||
const row = $(".message_edit_content").filter(":focus").closest(".message_row");
|
const row = $(".message_edit_content").filter(":focus").closest(".message_row");
|
||||||
const message_edit_save_button = row.find(".message_edit_save");
|
const message_edit_save_button = row.find(".message_edit_save");
|
||||||
if (message_edit_save_button.prop("disabled")) {
|
if (message_edit_save_button.prop("disabled")) {
|
||||||
// In cases when the save button is disabled
|
// In cases when the save button is disabled
|
||||||
// we need to disable save on pressing enter
|
// we need to disable save on pressing Enter
|
||||||
// Prevent default to avoid new-line on pressing
|
// Prevent default to avoid new-line on pressing
|
||||||
// enter inside the textarea in this case
|
// Enter inside the textarea in this case
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -230,13 +230,13 @@ function handle_inline_topic_edit_keydown(e) {
|
|||||||
let row;
|
let row;
|
||||||
const code = e.keyCode || e.which;
|
const code = e.keyCode || e.which;
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 13: // Handle enter key in the recipient bar/inline topic edit form
|
case 13: // Handle Enter key in the recipient bar/inline topic edit form
|
||||||
row = $(e.target).closest(".recipient_row");
|
row = $(e.target).closest(".recipient_row");
|
||||||
exports.save_inline_topic_edit(row);
|
exports.save_inline_topic_edit(row);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
case 27: // handle escape
|
case 27: // handle Esc
|
||||||
exports.end_if_focused_on_inline_topic_edit();
|
exports.end_if_focused_on_inline_topic_edit();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ exports.initialize = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
searchbox_form.on("compositionend", () => {
|
searchbox_form.on("compositionend", () => {
|
||||||
// Set `is_using_input_method` to true if enter is pressed to exit
|
// Set `is_using_input_method` to true if Enter is pressed to exit
|
||||||
// the input tool popover and get the text in the search bar. Then
|
// the input tool popover and get the text in the search bar. Then
|
||||||
// we suppress searching triggered by this enter key by checking
|
// we suppress searching triggered by this Enter key by checking
|
||||||
// `is_using_input_method` before searching.
|
// `is_using_input_method` before searching.
|
||||||
// More details in the commit message that added this line.
|
// More details in the commit message that added this line.
|
||||||
exports.is_using_input_method = true;
|
exports.is_using_input_method = true;
|
||||||
@@ -140,7 +140,7 @@ exports.initialize = function () {
|
|||||||
}
|
}
|
||||||
const code = e.which;
|
const code = e.which;
|
||||||
if (code === 13 && search_query_box.is(":focus")) {
|
if (code === 13 && search_query_box.is(":focus")) {
|
||||||
// We just pressed enter and the box had focus, which
|
// We just pressed Enter and the box had focus, which
|
||||||
// means we didn't use the typeahead at all. In that
|
// means we didn't use the typeahead at all. In that
|
||||||
// case, we should act as though we're searching by
|
// case, we should act as though we're searching by
|
||||||
// operators. (The reason the other actions don't call
|
// operators. (The reason the other actions don't call
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ function create_stream() {
|
|||||||
created_stream = stream_name;
|
created_stream = stream_name;
|
||||||
|
|
||||||
// Even though we already check to make sure that while typing the user cannot enter
|
// Even though we already check to make sure that while typing the user cannot enter
|
||||||
// newline characters (by pressing the enter key) it would still be possible to copy
|
// newline characters (by pressing the Enter key) it would still be possible to copy
|
||||||
// and paste over a description with newline characters in it. Prevent that.
|
// and paste over a description with newline characters in it. Prevent that.
|
||||||
if (description.includes("\n")) {
|
if (description.includes("\n")) {
|
||||||
ui_report.message(
|
ui_report.message(
|
||||||
|
|||||||
@@ -929,7 +929,7 @@ exports.initialize = function () {
|
|||||||
$(".subscriptions").on("click", "[data-dismiss]", (e) => {
|
$(".subscriptions").on("click", "[data-dismiss]", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// we want to make sure that the click is not just a simulated
|
// we want to make sure that the click is not just a simulated
|
||||||
// click; this fixes an issue where hitting "enter" would
|
// click; this fixes an issue where hitting "Enter" would
|
||||||
// trigger this code path due to bootstrap magic.
|
// trigger this code path due to bootstrap magic.
|
||||||
if (e.clientY !== 0) {
|
if (e.clientY !== 0) {
|
||||||
exports.show_subs_pane.nothing_selected();
|
exports.show_subs_pane.nothing_selected();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ mirror script instead of using Webathena.</p>
|
|||||||
<ol>
|
<ol>
|
||||||
<li>Run <code>screen -x zulip</code> to connect to the mirroring
|
<li>Run <code>screen -x zulip</code> to connect to the mirroring
|
||||||
screen session created above.</li>
|
screen session created above.</li>
|
||||||
<li>The first time, you'll need to type <code>ctrl-a c</code> to switch to a new terminal in your screen session.</li>
|
<li>The first time, you'll need to type <code>Ctrl-A c</code> to switch to a new terminal in your screen session.</li>
|
||||||
<li><code>kinit -l7d && aklog</code></li>
|
<li><code>kinit -l7d && aklog</code></li>
|
||||||
<li>(Type type your password to renew your Kerberos tickets).</li>
|
<li>(Type type your password to renew your Kerberos tickets).</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ There are several ways to access an existing PM or group PM.
|
|||||||
* Click on any user or group in the right sidebar.
|
* Click on any user or group in the right sidebar.
|
||||||
* Start typing a user's name in [search](/help/search-for-messages). You'll be
|
* Start typing a user's name in [search](/help/search-for-messages). You'll be
|
||||||
able to select PMs or group PMs with that user.
|
able to select PMs or group PMs with that user.
|
||||||
* Open the compose box, and enter in a (list of) users. Type `Ctr + .` (or
|
* Open the compose box, and enter in a (list of) users. Type `Ctrl + .` (or
|
||||||
`Cmd + .` on a mac) to open that conversation.
|
`Cmd + .` on a mac) to open that conversation.
|
||||||
|
|||||||
@@ -6963,7 +6963,7 @@ paths:
|
|||||||
description: |
|
description: |
|
||||||
Present if `realm_user` is present in `fetch_event_types`.
|
Present if `realm_user` is present in `fetch_event_types`.
|
||||||
|
|
||||||
Whether the user setting for [sending on pressing enter](/help/enable-enter-to-send)
|
Whether the user setting for [sending on pressing Enter](/help/enable-enter-to-send)
|
||||||
in the compose box is enabled.
|
in the compose box is enabled.
|
||||||
user_id:
|
user_id:
|
||||||
type: integer
|
type: integer
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ def _reload():
|
|||||||
# re-executing in the current process, start a new one
|
# re-executing in the current process, start a new one
|
||||||
# and cause the current process to exit. This isn't
|
# and cause the current process to exit. This isn't
|
||||||
# ideal since the new process is detached from the parent
|
# ideal since the new process is detached from the parent
|
||||||
# terminal and thus cannot easily be killed with ctrl-C,
|
# terminal and thus cannot easily be killed with Ctrl-C,
|
||||||
# but it's better than not being able to autoreload at
|
# but it's better than not being able to autoreload at
|
||||||
# all.
|
# all.
|
||||||
# Unfortunately the errno returned in this case does not
|
# Unfortunately the errno returned in this case does not
|
||||||
|
|||||||
Reference in New Issue
Block a user