DEV: Normalize key modifier checks for keyboard shortcuts (#22451)

This introduces a PLATFORM_KEY_MODIFIER const that
can be used both client and server side, to determine
whether we should be using the Meta or Ctrl key based
on whether the user is on Windows/Linux or Mac.
This commit is contained in:
Martin Brennan 2023-07-06 13:34:24 +10:00 committed by GitHub
parent 4c810703c1
commit 1cd512a03a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 57 additions and 53 deletions

View File

@ -1,4 +1,5 @@
import { ajax } from "discourse/lib/ajax";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import {
caretPosition,
inCodeBlock,
@ -180,15 +181,14 @@ class Toolbar {
const title = I18n.t(button.title || `composer.${button.id}_title`);
if (button.shortcut) {
const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
const mod = mac ? "Meta" : "Ctrl";
const shortcutTitle = `${translateModKey(mod + "+")}${translateModKey(
button.shortcut
)}`;
const shortcutTitle = `${translateModKey(
PLATFORM_KEY_MODIFIER + "+"
)}${translateModKey(button.shortcut)}`;
createdButton.title = `${title} (${shortcutTitle})`;
this.shortcuts[`${mod}+${button.shortcut}`.toLowerCase()] = createdButton;
this.shortcuts[
`${PLATFORM_KEY_MODIFIER}+${button.shortcut}`.toLowerCase()
] = createdButton;
} else {
createdButton.title = title;
}
@ -304,11 +304,9 @@ export default Component.extend(TextareaTextManipulation, {
this._itsatrap.bind("tab", () => this.indentSelection("right"));
this._itsatrap.bind("shift+tab", () => this.indentSelection("left"));
const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
const mod = mac ? "meta" : "ctrl";
this._itsatrap.bind(`${mod}+shift+.`, () => this.send("insertCurrentTime"));
this._itsatrap.bind(`${PLATFORM_KEY_MODIFIER}+shift+.`, () =>
this.send("insertCurrentTime")
);
// disable clicking on links in the preview
this.element

View File

@ -33,6 +33,12 @@ export function clearExtraKeyboardShortcutHelp() {
export { extraKeyboardShortcutsHelp as extraKeyboardShortcutsHelp };
export const PLATFORM_KEY_MODIFIER = /Mac|iPod|iPhone|iPad/.test(
navigator.platform
)
? "meta"
: "ctrl";
const DEFAULT_BINDINGS = {
"!": { postAction: "showFlags" },
"#": { handler: "goToPost", anonymous: true },

View File

@ -520,16 +520,18 @@ export function translateModKey(string) {
// Apple device users are used to glyphs for shortcut keys
if (isApple) {
string = string
.replace("Shift", "\u21E7")
.replace("Meta", "\u2318")
.replace("Alt", "\u2325")
.toLowerCase()
.replace("shift", "\u21E7")
.replace("meta", "\u2318")
.replace("alt", "\u2325")
.replace(/\+/g, "");
} else {
string = string
.replace("Shift", I18n.t("shortcut_modifier_key.shift"))
.replace("Ctrl", I18n.t("shortcut_modifier_key.ctrl"))
.replace("Meta", I18n.t("shortcut_modifier_key.ctrl"))
.replace("Alt", I18n.t("shortcut_modifier_key.alt"));
.toLowerCase()
.replace("shift", I18n.t("shortcut_modifier_key.shift"))
.replace("ctrl", I18n.t("shortcut_modifier_key.ctrl"))
.replace("meta", I18n.t("shortcut_modifier_key.ctrl"))
.replace("alt", I18n.t("shortcut_modifier_key.alt"));
}
return string;

View File

@ -7,6 +7,7 @@ import {
triggerKeyEvent,
visit,
} from "@ember/test-helpers";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { toggleCheckDraftPopup } from "discourse/services/composer";
import { cloneJSON } from "discourse-common/lib/object";
import TopicFixtures from "discourse/tests/fixtures/topic";
@ -217,10 +218,9 @@ acceptance("Composer", function (needs) {
textarea.selectionEnd = textarea.value.length;
// Testing keyboard events is tough!
const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
const event = document.createEvent("Event");
event.initEvent("keydown", true, true);
event[mac ? "metaKey" : "ctrlKey"] = true;
event[`${PLATFORM_KEY_MODIFIER}Key`] = true;
event.key = "B";
event.keyCode = 66;
@ -1371,14 +1371,14 @@ acceptance("Composer - current time", function (needs) {
assert.ok(exists(".d-editor-input"), "the composer input is visible");
await fillIn(".d-editor-input", "and the time now is: ");
const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
const date = moment().format("YYYY-MM-DD");
await triggerKeyEvent(".d-editor-input", "keydown", ".", {
const eventOptions = {
shiftKey: true,
ctrlKey: !mac,
metaKey: mac,
});
};
eventOptions[`${PLATFORM_KEY_MODIFIER}Key`] = true;
await triggerKeyEvent(".d-editor-input", "keydown", ".", eventOptions);
const inputValue = query("#reply-control .d-editor-input").value.trim();

View File

@ -1,10 +1,7 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import ChatNewMessageModal from "discourse/plugins/chat/discourse/components/modal/chat-new-message";
const APPLE =
navigator.platform.startsWith("Mac") || navigator.platform === "iPhone";
export const KEY_MODIFIER = APPLE ? "meta" : "ctrl";
export default {
name: "chat-keyboard-shortcuts",
@ -127,17 +124,21 @@ export default {
};
withPluginApi("0.12.1", (api) => {
api.addKeyboardShortcut(`${KEY_MODIFIER}+k`, openChannelSelector, {
global: true,
help: {
category: "chat",
name: "chat.keyboard_shortcuts.open_quick_channel_selector",
definition: {
keys1: ["meta", "k"],
keysDelimiter: "plus",
api.addKeyboardShortcut(
`${PLATFORM_KEY_MODIFIER}+k`,
openChannelSelector,
{
global: true,
help: {
category: "chat",
name: "chat.keyboard_shortcuts.open_quick_channel_selector",
definition: {
keys1: ["meta", "k"],
keysDelimiter: "plus",
},
},
},
});
}
);
api.addKeyboardShortcut("alt+up", handleMoveUpShortcut, {
global: true,
help: {
@ -156,7 +157,7 @@ export default {
global: true,
});
api.addKeyboardShortcut(
`${KEY_MODIFIER}+b`,
`${PLATFORM_KEY_MODIFIER}+b`,
(event) => modifyComposerSelection(event, "bold"),
{
global: true,
@ -171,7 +172,7 @@ export default {
}
);
api.addKeyboardShortcut(
`${KEY_MODIFIER}+i`,
`${PLATFORM_KEY_MODIFIER}+i`,
(event) => modifyComposerSelection(event, "italic"),
{
global: true,
@ -186,7 +187,7 @@ export default {
}
);
api.addKeyboardShortcut(
`${KEY_MODIFIER}+e`,
`${PLATFORM_KEY_MODIFIER}+e`,
(event) => modifyComposerSelection(event, "code"),
{
global: true,
@ -201,7 +202,7 @@ export default {
}
);
api.addKeyboardShortcut(
`${KEY_MODIFIER}+l`,
`${PLATFORM_KEY_MODIFIER}+l`,
(event) => openInsertLinkModal(event),
{
global: true,

View File

@ -7,7 +7,6 @@ RSpec.describe "Chat | composer | shortcuts | channel", type: :system do
let(:chat) { PageObjects::Pages::Chat.new }
let(:channel_page) { PageObjects::Pages::ChatChannel.new }
let(:thread_page) { PageObjects::Pages::ChatThread.new }
let(:key_modifier) { RUBY_PLATFORM =~ /darwin/i ? :meta : :control }
before do
chat_system_bootstrap

View File

@ -3,8 +3,6 @@
module PageObjects
module Pages
class Chat < PageObjects::Pages::Base
MODIFIER = RUBY_PLATFORM =~ /darwin/i ? :meta : :control
def message_creator
@message_creator ||= PageObjects::Components::Chat::MessageCreator.new
end
@ -24,7 +22,7 @@ module PageObjects
end
def open_new_message
send_keys([MODIFIER, "k"])
send_keys([PLATFORM_KEY_MODIFIER, "k"])
find(".chat-new-message-modal")
end

View File

@ -8,8 +8,6 @@ module PageObjects
SELECTOR = ".chat-composer__wrapper"
MODIFIER = RUBY_PLATFORM =~ /darwin/i ? :meta : :control
def initialize(context)
@context = context
end
@ -59,7 +57,7 @@ module PageObjects
end
def emphasized_text_shortcut
input.send_keys([MODIFIER, "i"])
input.send_keys([PLATFORM_KEY_MODIFIER, "i"])
end
def cancel_shortcut
@ -67,11 +65,11 @@ module PageObjects
end
def indented_text_shortcut
input.send_keys([MODIFIER, "e"])
input.send_keys([PLATFORM_KEY_MODIFIER, "e"])
end
def bold_text_shortcut
input.send_keys([MODIFIER, "b"])
input.send_keys([PLATFORM_KEY_MODIFIER, "b"])
end
def open_emoji_picker

View File

@ -2,6 +2,8 @@
require "highline/import"
module SystemHelpers
PLATFORM_KEY_MODIFIER = RUBY_PLATFORM =~ /darwin/i ? :meta : :control
def pause_test
result =
ask(