mac_shortcuts: Render shortcuts with `Fn` key correctly.

Updates the `adjusts_mac_shortcuts` function to render shortcuts
with the `Fn` key as a separate html element (e.g. `Fn` + `arrow`)
instead of rendering the shortcut as one block (e.g. `Fn + arrow`).

Also, because keyboard shortcuts should be rendered with each key
as a separate html element, updates `adjusts_mac_shortcuts` to
only change html elements that are an exact match to a keyboard
key. Html elements with whitespace will be ignored (e.g. `Enter`
becomes `Return`, but `Enter or Backspace` is not changed though
it previously would have been changed to `Return or Delete`).

Fixes #22112 (in combination with #22273).
This commit is contained in:
Lauryn Menard 2022-06-21 17:58:02 +02:00 committed by Tim Abbott
parent 22c4763a61
commit 24d1d08553
3 changed files with 105 additions and 23 deletions

View File

@ -88,22 +88,27 @@ run_test("adjust_mac_shortcuts non-mac", ({override_rewire}) => {
common.adjust_mac_shortcuts("selector-that-does-not-exist");
});
run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
// Test non-default values of adjust_mac_shortcuts boolean parameters:
// `kbd_elem = false`, and `require_cmd_style = true`.
run_test("adjust_mac_shortcuts mac non-defaults", ({override_rewire}) => {
const keys_to_test_mac = new Map([
["Backspace", "Delete"],
["Enter", "Return"],
["Home", "Fn + ←"],
["End", "Fn + →"],
["PgUp", "Fn + ↑"],
["PgDn", "Fn + ↓"],
["Home", "←"],
["End", "→"],
["PgUp", "↑"],
["PgDn", "↓"],
["Ctrl", "⌘"],
["X + Shift", "X + Shift"],
["⌘ + Return", "⌘ + Return"],
["Enter or Backspace", "Return or Delete"],
["Ctrl", "⌘"],
["Ctrl + Shift", "⌘ + Shift"],
["Ctrl + Backspace + End", "⌘ + Delete + Fn + →"],
["Enter or Backspace", "Enter or Backspace"],
["#stream_name", "#stream_name"],
["Ctrl+K", "Ctrl+K"],
]);
const fn_shortcuts = new Set(["Home", "End", "PgUp", "PgDn"]);
const inserted_fn_key = "<code>Fn</code> + ";
override_rewire(common, "has_mac_keyboard", () => true);
const test_items = [];
@ -114,9 +119,14 @@ run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
const $stub = $.create("hotkey_" + key_no);
$stub.text(old_key);
assert.equal($stub.hasClass("mac-cmd-key"), false);
if (fn_shortcuts.has(old_key)) {
$stub.before = ($elem) => {
assert.equal($elem, inserted_fn_key);
};
}
test_item.$stub = $stub;
test_item.mac_key = mac_key;
test_item.is_cmd_key = old_key.includes("Ctrl");
test_item.is_cmd_key = old_key === "Ctrl";
test_items.push(test_item);
key_no += 1;
}
@ -126,7 +136,8 @@ run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
$.create(".markdown_content", {children});
const require_cmd = true;
common.adjust_mac_shortcuts(".markdown_content", require_cmd);
const kbd_element = false;
common.adjust_mac_shortcuts(".markdown_content", kbd_element, require_cmd);
for (const test_item of test_items) {
assert.equal(test_item.$stub.hasClass("mac-cmd-key"), test_item.is_cmd_key);
@ -134,6 +145,57 @@ run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
}
});
// Test default values of adjust_mac_shortcuts boolean parameters:
// `kbd_elem = true`, and `require_cmd_style = false`.
run_test("adjust_mac_shortcuts mac defaults", ({override_rewire}) => {
const keys_to_test_mac = new Map([
["Backspace", "Delete"],
["Enter", "Return"],
["Home", "←"],
["End", "→"],
["PgUp", "↑"],
["PgDn", "↓"],
["Ctrl", "⌘"],
["[", "["],
["X", "X"],
]);
const fn_shortcuts = new Set(["Home", "End", "PgUp", "PgDn"]);
const inserted_fn_key = "<kbd>Fn</kbd> + ";
override_rewire(common, "has_mac_keyboard", () => true);
const test_items = [];
let key_no = 1;
for (const [old_key, mac_key] of keys_to_test_mac) {
const test_item = {};
const $stub = $.create("hotkey_" + key_no);
$stub.text(old_key);
assert.equal($stub.hasClass("mac-cmd-key"), false);
if (fn_shortcuts.has(old_key)) {
$stub.before = ($elem) => {
assert.equal($elem, inserted_fn_key);
};
}
test_item.$stub = $stub;
test_item.mac_key = mac_key;
test_items.push(test_item);
key_no += 1;
}
const children = test_items.map((test_item) => ({to_$: () => test_item.$stub}));
$.create(".hotkeys_table kbd", {children});
common.adjust_mac_shortcuts(".hotkeys_table kbd");
for (const test_item of test_items) {
assert.equal(test_item.$stub.hasClass("mac-cmd-key"), false);
assert.equal(test_item.$stub.text(), test_item.mac_key);
}
});
run_test("show password", () => {
const password_selector = "#id_password ~ .password_visibility_toggle";

View File

@ -48,7 +48,11 @@ export function has_mac_keyboard(): boolean {
return /mac/i.test(navigator.platform);
}
export function adjust_mac_shortcuts(key_elem_class: string, require_cmd_style = false): void {
export function adjust_mac_shortcuts(
key_elem_class: string,
kbd_elem = true,
require_cmd_style = false,
): void {
if (!has_mac_keyboard()) {
return;
}
@ -56,28 +60,44 @@ export function adjust_mac_shortcuts(key_elem_class: string, require_cmd_style =
const keys_map = new Map([
["Backspace", "Delete"],
["Enter", "Return"],
["Home", "Fn + ←"],
["End", "Fn + →"],
["PgUp", "Fn + ↑"],
["PgDn", "Fn + ↓"],
["Home", "←"],
["End", "→"],
["PgUp", "↑"],
["PgDn", "↓"],
["Ctrl", "⌘"],
]);
const fn_shortcuts = new Set(["Home", "End", "PgUp", "PgDn"]);
$(key_elem_class).each(function () {
let key_text = $(this).text();
const keys = key_text.match(/[^\s+]+/g) || [];
if (key_text.includes("Ctrl") && require_cmd_style) {
// There may be matches to `key_elem_class` that are not
// keyboard shortcuts. Since keyboard shortcuts should be an
// exact match to the text on a physical key of a keyboard,
// none of which have spaces, we check and return early for
// any matched element's text that contains whitespace.
if (/\s/.test(key_text)) {
return;
}
if (key_text === "Ctrl" && require_cmd_style) {
$(this).addClass("mac-cmd-key");
}
for (const key of keys) {
const replace_key = keys_map.get(key);
if (replace_key !== undefined) {
key_text = key_text.replace(key, replace_key);
if (fn_shortcuts.has(key_text)) {
if (kbd_elem) {
$(this).before("<kbd>Fn</kbd> + ");
} else {
$(this).before("<code>Fn</code> + ");
}
}
const replace_key = keys_map.get(key_text);
if (replace_key !== undefined) {
key_text = replace_key;
}
$(this).text(key_text);
});
}

View File

@ -58,7 +58,7 @@ function render_code_sections() {
highlight_current_article();
common.adjust_mac_shortcuts(".markdown .content code", true);
common.adjust_mac_shortcuts(".markdown .content code", false, true);
$("table").each(function () {
$(this).addClass("table table-striped");