mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
hotkey: Convert module to typescript.
This commit is contained in:
@@ -121,7 +121,7 @@ EXEMPT_FILES = make_set(
|
|||||||
"web/src/hash_util.ts",
|
"web/src/hash_util.ts",
|
||||||
"web/src/hashchange.ts",
|
"web/src/hashchange.ts",
|
||||||
"web/src/hbs.d.ts",
|
"web/src/hbs.d.ts",
|
||||||
"web/src/hotkey.js",
|
"web/src/hotkey.ts",
|
||||||
"web/src/inbox_ui.ts",
|
"web/src/inbox_ui.ts",
|
||||||
"web/src/inbox_util.ts",
|
"web/src/inbox_util.ts",
|
||||||
"web/src/info_overlay.ts",
|
"web/src/info_overlay.ts",
|
||||||
|
@@ -231,7 +231,7 @@ function get_quote_target(opts: {message_id?: number; quote_content?: string | u
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function quote_message(opts: {
|
export function quote_message(opts: {
|
||||||
message_id: number;
|
message_id?: number;
|
||||||
quote_content?: string | undefined;
|
quote_content?: string | undefined;
|
||||||
keep_composebox_empty?: boolean;
|
keep_composebox_empty?: boolean;
|
||||||
reply_type?: "personal";
|
reply_type?: "personal";
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
// Save the compose content cursor position and restore when we
|
// Save the compose content cursor position and restore when we
|
||||||
// shift-tab back in (see hotkey.js).
|
// shift-tab back in (see hotkey.ts).
|
||||||
let saved_compose_cursor = 0;
|
let saved_compose_cursor = 0;
|
||||||
|
|
||||||
function set_compose_textarea_handlers(): void {
|
function set_compose_textarea_handlers(): void {
|
||||||
|
@@ -75,7 +75,7 @@ export function show_flatpickr(
|
|||||||
assert(target !== undefined);
|
assert(target !== undefined);
|
||||||
target.focus();
|
target.focus();
|
||||||
} else {
|
} else {
|
||||||
// Prevent keypresses from propagating to our general hotkey.js
|
// Prevent keypresses from propagating to our general hotkey.ts
|
||||||
// logic. Without this, `Up` will navigate both in the
|
// logic. Without this, `Up` will navigate both in the
|
||||||
// flatpickr instance and in the message feed behind
|
// flatpickr instance and in the message feed behind
|
||||||
// it.
|
// it.
|
||||||
|
@@ -65,8 +65,16 @@ import * as user_card_popover from "./user_card_popover.ts";
|
|||||||
import * as user_group_popover from "./user_group_popover.ts";
|
import * as user_group_popover from "./user_group_popover.ts";
|
||||||
import {user_settings} from "./user_settings.ts";
|
import {user_settings} from "./user_settings.ts";
|
||||||
import * as user_topics_ui from "./user_topics_ui.ts";
|
import * as user_topics_ui from "./user_topics_ui.ts";
|
||||||
|
import * as util from "./util.ts";
|
||||||
|
|
||||||
function do_narrow_action(action) {
|
function do_narrow_action(
|
||||||
|
action: (
|
||||||
|
target_id: number,
|
||||||
|
opts: {
|
||||||
|
trigger: string;
|
||||||
|
},
|
||||||
|
) => void,
|
||||||
|
): boolean {
|
||||||
if (message_lists.current === undefined) {
|
if (message_lists.current === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -107,6 +115,11 @@ const KNOWN_IGNORE_SHIFT_MODIFIER_KEYS = new Set([
|
|||||||
"@",
|
"@",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
type Hotkey = {
|
||||||
|
name: string;
|
||||||
|
message_view_only: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
// Note that multiple keys can map to the same event_name, which
|
// Note that multiple keys can map to the same event_name, which
|
||||||
// we'll do in cases where they have the exact same semantics.
|
// we'll do in cases where they have the exact same semantics.
|
||||||
// DON'T FORGET: update keyboard_shortcuts.html
|
// DON'T FORGET: update keyboard_shortcuts.html
|
||||||
@@ -117,7 +130,7 @@ const KNOWN_IGNORE_SHIFT_MODIFIER_KEYS = new Set([
|
|||||||
// 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_MAPPINGS = {
|
const KEYDOWN_MAPPINGS: Record<string, Hotkey | Hotkey[]> = {
|
||||||
"Alt+P": {name: "toggle_compose_preview", message_view_only: true},
|
"Alt+P": {name: "toggle_compose_preview", message_view_only: true},
|
||||||
"Ctrl+[": {name: "escape", message_view_only: false},
|
"Ctrl+[": {name: "escape", message_view_only: false},
|
||||||
"Cmd+Enter": {name: "action_with_enter", message_view_only: true},
|
"Cmd+Enter": {name: "action_with_enter", message_view_only: true},
|
||||||
@@ -239,7 +252,7 @@ const KNOWN_NAMED_KEY_ATTRIBUTE_VALUES = new Set([
|
|||||||
"Tab",
|
"Tab",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const CODE_TO_QWERTY_CHAR = {
|
const CODE_TO_QWERTY_CHAR: Record<string, string> = {
|
||||||
KeyA: "a",
|
KeyA: "a",
|
||||||
KeyB: "b",
|
KeyB: "b",
|
||||||
KeyC: "c",
|
KeyC: "c",
|
||||||
@@ -310,7 +323,7 @@ const CODE_TO_QWERTY_CHAR = {
|
|||||||
|
|
||||||
// Keyboard Event Viewer tool:
|
// Keyboard Event Viewer tool:
|
||||||
// https://w3c.github.io/uievents/tools/key-event-viewer.html
|
// https://w3c.github.io/uievents/tools/key-event-viewer.html
|
||||||
export function get_keydown_hotkey(e) {
|
export function get_keydown_hotkey(e: JQuery.KeyDownEvent): Hotkey | Hotkey[] | undefined {
|
||||||
// Determine the key pressed in a consistent way.
|
// Determine the key pressed in a consistent way.
|
||||||
//
|
//
|
||||||
// For keyboard layouts (e.g. QWERTY) where `e.key` results
|
// For keyboard layouts (e.g. QWERTY) where `e.key` results
|
||||||
@@ -327,7 +340,11 @@ export function get_keydown_hotkey(e) {
|
|||||||
let key = e.key;
|
let key = e.key;
|
||||||
if (!use_event_key) {
|
if (!use_event_key) {
|
||||||
const code = `${e.shiftKey ? "Shift+" : ""}${e.code}`;
|
const code = `${e.shiftKey ? "Shift+" : ""}${e.code}`;
|
||||||
key = CODE_TO_QWERTY_CHAR[code];
|
if (CODE_TO_QWERTY_CHAR[code]) {
|
||||||
|
key = CODE_TO_QWERTY_CHAR[code];
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common.has_mac_keyboard() && e.ctrlKey && key !== "[") {
|
if (common.has_mac_keyboard() && e.ctrlKey && key !== "[") {
|
||||||
@@ -362,7 +379,7 @@ export function get_keydown_hotkey(e) {
|
|||||||
return KEYDOWN_MAPPINGS[key];
|
return KEYDOWN_MAPPINGS[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
export let processing_text = () => {
|
export let processing_text = (): boolean => {
|
||||||
const $focused_elt = $(":focus");
|
const $focused_elt = $(":focus");
|
||||||
return (
|
return (
|
||||||
$focused_elt.is("input") ||
|
$focused_elt.is("input") ||
|
||||||
@@ -374,16 +391,13 @@ export let processing_text = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function rewire_processing_text(value) {
|
export function rewire_processing_text(value: typeof processing_text): void {
|
||||||
processing_text = value;
|
processing_text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function in_content_editable_widget(e) {
|
|
||||||
return $(e.target).is(".editable-section");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if we handled it, false if the browser should.
|
// Returns true if we handled it, false if the browser should.
|
||||||
export function process_escape_key(e) {
|
function process_escape_key(e: JQuery.KeyDownEvent): boolean {
|
||||||
|
assert(e.target instanceof HTMLElement);
|
||||||
if (
|
if (
|
||||||
recent_view_ui.is_in_focus() &&
|
recent_view_ui.is_in_focus() &&
|
||||||
// This will return false if `e.target` is not
|
// This will return false if `e.target` is not
|
||||||
@@ -514,7 +528,7 @@ export function process_escape_key(e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_popover_events(event_name) {
|
function handle_popover_events(event_name: string): boolean {
|
||||||
const popover_menu_visible_instance = popover_menus.get_visible_instance();
|
const popover_menu_visible_instance = popover_menus.get_visible_instance();
|
||||||
|
|
||||||
if (popover_menus.is_stream_actions_popover_displayed()) {
|
if (popover_menus.is_stream_actions_popover_displayed()) {
|
||||||
@@ -570,7 +584,7 @@ function handle_popover_events(event_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if we handled it, false if the browser should.
|
// Returns true if we handled it, false if the browser should.
|
||||||
export function process_enter_key(e) {
|
function process_enter_key(e: JQuery.KeyDownEvent): boolean {
|
||||||
if ($(e.target).hasClass("trigger-click-on-enter")) {
|
if ($(e.target).hasClass("trigger-click-on-enter")) {
|
||||||
// If the target has the class "trigger-click-on-enter", explicitly
|
// If the target has the class "trigger-click-on-enter", explicitly
|
||||||
// trigger a click event on it to call the associated click handler.
|
// trigger a click event on it to call the associated click handler.
|
||||||
@@ -583,6 +597,7 @@ export function process_enter_key(e) {
|
|||||||
// If a popover is open and we pressed Enter on a menu item,
|
// If a popover is open and we pressed Enter on a menu item,
|
||||||
// call click directly on the item to navigate to the `href`.
|
// call click directly on the item to navigate to the `href`.
|
||||||
// trigger("click") doesn't work for them to navigate to `href`.
|
// trigger("click") doesn't work for them to navigate to `href`.
|
||||||
|
assert(e.target instanceof HTMLElement);
|
||||||
e.target.click();
|
e.target.click();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
popovers.hide_all();
|
popovers.hide_all();
|
||||||
@@ -636,6 +651,7 @@ export function process_enter_key(e) {
|
|||||||
// Transfer the enter keypress from button to the `<i>` tag inside
|
// Transfer the enter keypress from button to the `<i>` tag inside
|
||||||
// it since it is the trigger for the popover. <button> is already used
|
// it since it is the trigger for the popover. <button> is already used
|
||||||
// to trigger the tooltip so it cannot be used to trigger the popover.
|
// to trigger the tooltip so it cannot be used to trigger the popover.
|
||||||
|
assert(e.target instanceof HTMLElement);
|
||||||
if (e.target.id === "send_later") {
|
if (e.target.id === "send_later") {
|
||||||
compose_send_menu_popover.toggle();
|
compose_send_menu_popover.toggle();
|
||||||
return true;
|
return true;
|
||||||
@@ -705,7 +721,7 @@ export function process_enter_key(e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location = hash_util.by_conversation_and_time_url(message);
|
window.location.href = hash_util.by_conversation_and_time_url(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +729,7 @@ export function process_enter_key(e) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function process_cmd_or_ctrl_enter_key() {
|
export function process_cmd_or_ctrl_enter_key(): boolean {
|
||||||
if ($("#compose").hasClass("preview_mode")) {
|
if ($("#compose").hasClass("preview_mode")) {
|
||||||
const cmd_or_ctrl_pressed = true;
|
const cmd_or_ctrl_pressed = true;
|
||||||
compose.handle_enter_key_with_preview_open(cmd_or_ctrl_pressed);
|
compose.handle_enter_key_with_preview_open(cmd_or_ctrl_pressed);
|
||||||
@@ -723,7 +739,7 @@ export function process_cmd_or_ctrl_enter_key() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function process_tab_key() {
|
export function process_tab_key(): boolean {
|
||||||
// Returns true if we handled it, false if the browser should.
|
// Returns true if we handled it, false if the browser should.
|
||||||
// TODO: See if browsers like Safari can now handle tabbing correctly
|
// TODO: See if browsers like Safari can now handle tabbing correctly
|
||||||
// without our intervention.
|
// without our intervention.
|
||||||
@@ -752,7 +768,7 @@ export function process_tab_key() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function process_shift_tab_key() {
|
export function process_shift_tab_key(): boolean {
|
||||||
// Returns true if we handled it, false if the browser should.
|
// Returns true if we handled it, false if the browser should.
|
||||||
// TODO: See if browsers like Safari can now handle tabbing correctly
|
// TODO: See if browsers like Safari can now handle tabbing correctly
|
||||||
// without our intervention.
|
// without our intervention.
|
||||||
@@ -796,7 +812,7 @@ export function process_shift_tab_key() {
|
|||||||
// Process a keydown event.
|
// Process a keydown event.
|
||||||
//
|
//
|
||||||
// Returns true if we handled it, false if the browser should.
|
// Returns true if we handled it, false if the browser should.
|
||||||
export function process_hotkey(e, hotkey) {
|
function process_hotkey(e: JQuery.KeyDownEvent, hotkey: Hotkey): boolean {
|
||||||
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.
|
||||||
@@ -815,6 +831,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
case "shift_tab":
|
case "shift_tab":
|
||||||
case "open_recent_view":
|
case "open_recent_view":
|
||||||
if (recent_view_ui.is_in_focus()) {
|
if (recent_view_ui.is_in_focus()) {
|
||||||
|
assert(e.target instanceof HTMLElement);
|
||||||
return recent_view_ui.change_focused_element($(e.target), event_name);
|
return recent_view_ui.change_focused_element($(e.target), event_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -844,7 +861,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
case "enter":
|
case "enter":
|
||||||
return process_enter_key(e);
|
return process_enter_key(e);
|
||||||
case "action_with_enter":
|
case "action_with_enter":
|
||||||
return process_cmd_or_ctrl_enter_key(e);
|
return process_cmd_or_ctrl_enter_key();
|
||||||
case "tab":
|
case "tab":
|
||||||
return process_tab_key();
|
return process_tab_key();
|
||||||
case "shift_tab":
|
case "shift_tab":
|
||||||
@@ -952,9 +969,11 @@ export function process_hotkey(e, hotkey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event_name === "toggle_compose_preview") {
|
if (event_name === "toggle_compose_preview") {
|
||||||
const $last_focused_compose_type_input = $(
|
const last_focused_compose_type_input = compose_state.get_last_focused_compose_type_input();
|
||||||
compose_state.get_last_focused_compose_type_input(),
|
if (last_focused_compose_type_input === undefined) {
|
||||||
);
|
return false;
|
||||||
|
}
|
||||||
|
const $last_focused_compose_type_input = $(last_focused_compose_type_input);
|
||||||
|
|
||||||
if ($last_focused_compose_type_input.hasClass("message_edit_content")) {
|
if ($last_focused_compose_type_input.hasClass("message_edit_content")) {
|
||||||
if ($last_focused_compose_type_input.closest(".preview_mode").length > 0) {
|
if ($last_focused_compose_type_input.closest(".preview_mode").length > 0) {
|
||||||
@@ -1011,7 +1030,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
if (event_name === "open_saved_snippet_dropdown") {
|
if (event_name === "open_saved_snippet_dropdown") {
|
||||||
const $messagebox = $(":focus").parents(".messagebox");
|
const $messagebox = $(":focus").parents(".messagebox");
|
||||||
if ($messagebox.length === 1) {
|
if ($messagebox.length === 1) {
|
||||||
$messagebox.find(".saved_snippets_widget")[0].click();
|
util.the($messagebox.find(".saved_snippets_widget")).click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1029,7 +1048,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
if (event_name === "up_arrow" && $(":focus").attr("id") === "search_query") {
|
if (event_name === "up_arrow" && $(":focus").attr("id") === "search_query") {
|
||||||
$("#search_query").trigger("blur");
|
$("#search_query").trigger("blur");
|
||||||
message_scroll_state.set_keyboard_triggered_current_scroll(true);
|
message_scroll_state.set_keyboard_triggered_current_scroll(true);
|
||||||
navigate.up(true);
|
navigate.up();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -1047,7 +1066,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
return true;
|
return true;
|
||||||
case "page_down": {
|
case "page_down": {
|
||||||
// so that it always goes to the end of the text box.
|
// so that it always goes to the end of the text box.
|
||||||
const height = $(":focus")[0].scrollHeight;
|
const height = util.the($(":focus")).scrollHeight;
|
||||||
$(":focus")
|
$(":focus")
|
||||||
.caret(Number.POSITIVE_INFINITY)
|
.caret(Number.POSITIVE_INFINITY)
|
||||||
.animate({scrollTop: height}, "fast");
|
.animate({scrollTop: height}, "fast");
|
||||||
@@ -1188,9 +1207,9 @@ export function process_hotkey(e, hotkey) {
|
|||||||
if (inbox_ui.is_in_focus()) {
|
if (inbox_ui.is_in_focus()) {
|
||||||
return inbox_ui.toggle_topic_visibility_policy();
|
return inbox_ui.toggle_topic_visibility_policy();
|
||||||
}
|
}
|
||||||
if (message_lists.current.selected_message()) {
|
if (message_lists.current!.selected_message()) {
|
||||||
user_topics_ui.toggle_topic_visibility_policy(
|
user_topics_ui.toggle_topic_visibility_policy(
|
||||||
message_lists.current.selected_message(),
|
message_lists.current!.selected_message()!,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1322,6 +1341,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const msg = message_lists.current.selected_message();
|
const msg = message_lists.current.selected_message();
|
||||||
|
assert(msg !== undefined);
|
||||||
|
|
||||||
// Shortcuts that operate on a message
|
// Shortcuts that operate on a message
|
||||||
switch (event_name) {
|
switch (event_name) {
|
||||||
@@ -1364,9 +1384,9 @@ export function process_hotkey(e, hotkey) {
|
|||||||
$emoji_icon?.length !== 0 &&
|
$emoji_icon?.length !== 0 &&
|
||||||
$emoji_icon.closest(".message_control_button").css("display") !== "none"
|
$emoji_icon.closest(".message_control_button").css("display") !== "none"
|
||||||
) {
|
) {
|
||||||
emoji_picker_reference = $emoji_icon[0];
|
emoji_picker_reference = util.the($emoji_icon);
|
||||||
} else {
|
} else {
|
||||||
emoji_picker_reference = $row.find(".message-actions-menu-button")[0];
|
emoji_picker_reference = util.the($row.find(".message-actions-menu-button"));
|
||||||
}
|
}
|
||||||
|
|
||||||
emoji_picker.toggle_emoji_popover(emoji_picker_reference, msg.id, {
|
emoji_picker.toggle_emoji_popover(emoji_picker_reference, msg.id, {
|
||||||
@@ -1378,7 +1398,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
// '+': reacts with thumbs up emoji on selected message
|
// '+': reacts with thumbs up emoji on selected message
|
||||||
// Use canonical name.
|
// Use canonical name.
|
||||||
const thumbs_up_emoji_code = "1f44d";
|
const thumbs_up_emoji_code = "1f44d";
|
||||||
const canonical_name = emoji.get_emoji_name(thumbs_up_emoji_code);
|
const canonical_name = emoji.get_emoji_name(thumbs_up_emoji_code)!;
|
||||||
reactions.toggle_emoji_reaction(msg, canonical_name);
|
reactions.toggle_emoji_reaction(msg, canonical_name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1434,8 +1454,13 @@ export function process_hotkey(e, hotkey) {
|
|||||||
if (!message_edit.can_move_message(msg)) {
|
if (!message_edit.can_move_message(msg)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
assert(msg.type === "stream");
|
||||||
stream_popover.build_move_topic_to_stream_popover(msg.stream_id, msg.topic, false, msg);
|
void stream_popover.build_move_topic_to_stream_popover(
|
||||||
|
msg.stream_id,
|
||||||
|
msg.topic,
|
||||||
|
false,
|
||||||
|
msg,
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case "toggle_read_receipts": {
|
case "toggle_read_receipts": {
|
||||||
@@ -1476,7 +1501,7 @@ export function process_hotkey(e, hotkey) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function process_keydown(e) {
|
export function process_keydown(e: JQuery.KeyDownEvent): boolean {
|
||||||
activity.set_new_user_input(true);
|
activity.set_new_user_input(true);
|
||||||
const result = get_keydown_hotkey(e);
|
const result = get_keydown_hotkey(e);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -1489,7 +1514,7 @@ export function process_keydown(e) {
|
|||||||
return process_hotkey(e, result);
|
return process_hotkey(e, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize() {
|
export function initialize(): void {
|
||||||
$(document).on("keydown", (e) => {
|
$(document).on("keydown", (e) => {
|
||||||
if (e.key === undefined) {
|
if (e.key === undefined) {
|
||||||
/* Some browsers trigger a 'keydown' event with `key === undefined`
|
/* Some browsers trigger a 'keydown' event with `key === undefined`
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
See hotkey.js for handlers that are more app-wide.
|
See hotkey.ts for handlers that are more app-wide.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const vim_left = "h";
|
export const vim_left = "h";
|
||||||
|
@@ -55,7 +55,7 @@ import * as giphy from "./giphy.ts";
|
|||||||
import * as giphy_state from "./giphy_state.ts";
|
import * as giphy_state from "./giphy_state.ts";
|
||||||
import * as group_permission_settings from "./group_permission_settings.ts";
|
import * as group_permission_settings from "./group_permission_settings.ts";
|
||||||
import * as hashchange from "./hashchange.ts";
|
import * as hashchange from "./hashchange.ts";
|
||||||
import * as hotkey from "./hotkey.js";
|
import * as hotkey from "./hotkey.ts";
|
||||||
import * as i18n from "./i18n.ts";
|
import * as i18n from "./i18n.ts";
|
||||||
import * as inbox_ui from "./inbox_ui.ts";
|
import * as inbox_ui from "./inbox_ui.ts";
|
||||||
import * as information_density from "./information_density.ts";
|
import * as information_density from "./information_density.ts";
|
||||||
|
@@ -17,7 +17,7 @@ const {page_params} = require("./lib/zpage_params.cjs");
|
|||||||
// functions (like overlays.settings_open). Within that context, to
|
// functions (like overlays.settings_open). Within that context, to
|
||||||
// test whether a given key (e.g. `x`) results in a specific function
|
// test whether a given key (e.g. `x`) results in a specific function
|
||||||
// (e.g. `ui.foo()`), we fail to import any modules other than
|
// (e.g. `ui.foo()`), we fail to import any modules other than
|
||||||
// hotkey.js so that accessing them will result in a ReferenceError.
|
// hotkey.ts so that accessing them will result in a ReferenceError.
|
||||||
//
|
//
|
||||||
// Then we create a stub `ui.foo`, and call the hotkey function. If
|
// Then we create a stub `ui.foo`, and call the hotkey function. If
|
||||||
// it calls any external module other than `ui.foo`, it'll crash.
|
// it calls any external module other than `ui.foo`, it'll crash.
|
||||||
@@ -37,7 +37,7 @@ set_global("document", {
|
|||||||
|
|
||||||
const activity_ui = mock_esm("../src/activity_ui");
|
const activity_ui = mock_esm("../src/activity_ui");
|
||||||
const activity = zrequire("../src/activity");
|
const activity = zrequire("../src/activity");
|
||||||
const browser_history = mock_esm("../src/browser_history");
|
const browser_history = mock_esm("../src/browser_history", {go_to_location() {}});
|
||||||
const compose_actions = mock_esm("../src/compose_actions");
|
const compose_actions = mock_esm("../src/compose_actions");
|
||||||
const compose_reply = mock_esm("../src/compose_reply");
|
const compose_reply = mock_esm("../src/compose_reply");
|
||||||
const condense = mock_esm("../src/condense");
|
const condense = mock_esm("../src/condense");
|
||||||
@@ -106,7 +106,7 @@ message_lists.current = {
|
|||||||
},
|
},
|
||||||
selected_row() {
|
selected_row() {
|
||||||
const $row = $.create("selected-row-stub");
|
const $row = $.create("selected-row-stub");
|
||||||
$row.set_find_results(".message-actions-menu-button", []);
|
$row.set_find_results(".message-actions-menu-button", ["<menu-button-stub>"]);
|
||||||
$row.set_find_results(".emoji-message-control-button-container", {
|
$row.set_find_results(".emoji-message-control-button-container", {
|
||||||
closest: () => ({css: () => "none"}),
|
closest: () => ({css: () => "none"}),
|
||||||
});
|
});
|
||||||
@@ -114,6 +114,8 @@ message_lists.current = {
|
|||||||
},
|
},
|
||||||
selected_message() {
|
selected_message() {
|
||||||
return {
|
return {
|
||||||
|
type: "stream",
|
||||||
|
stream_id: 2,
|
||||||
sent_by_me: true,
|
sent_by_me: true,
|
||||||
flags: ["read", "starred"],
|
flags: ["read", "starred"],
|
||||||
};
|
};
|
||||||
@@ -355,11 +357,11 @@ function test_normal_typing() {
|
|||||||
assert_unmapped('~!@#$%^*()_+{}:"<>');
|
assert_unmapped('~!@#$%^*()_+{}:"<>');
|
||||||
}
|
}
|
||||||
|
|
||||||
test_while_not_editing_text("unmapped keys return false easily", () => {
|
run_test("unmapped keys return false easily", () => {
|
||||||
// Unmapped keys should immediately return false, without
|
// Unmapped keys should immediately return false, without
|
||||||
// calling any functions outside of hotkey.js.
|
// calling any functions outside of hotkey.ts.
|
||||||
// (unless we are editing text)
|
// (unless we are editing text)
|
||||||
assert_unmapped("bfoyz");
|
assert_unmapped("bfo");
|
||||||
assert_unmapped("BEFLOQTWXYZ");
|
assert_unmapped("BEFLOQTWXYZ");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user