tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestShortcutKeyDefinitions.cpp (47942B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "KeyEventHandler.h"
      8 #include "ShortcutKeys.h"
      9 #include "gtest/gtest.h"
     10 #include "mozilla/RefPtr.h"
     11 #include "mozilla/TextEvents.h"
     12 #include "mozilla/dom/KeyboardEvent.h"
     13 
     14 namespace mozilla {
     15 
     16 /**
     17 * These tests checks whether the key mapping defined by
     18 * `ShortcutKeyDefinitions.cpp` and its including header files.
     19 * Note that these tests do NOT define how shortcut keys mapped.  These tests
     20 * exist for checking unexpected change occurs by cleaning up or changing
     21 * the mapping.
     22 */
     23 
     24 #ifndef MOZ_WIDGET_COCOA
     25 #  define MODIFIER_ACCEL MODIFIER_CONTROL
     26 #else
     27 #  define MODIFIER_ACCEL MODIFIER_META
     28 #endif
     29 
     30 struct ShortcutKeyMap final {
     31  uint32_t const mKeyCode;
     32  char32_t const mCharCode;
     33  Modifiers const mModifiers;
     34  const char16ptr_t mCommandWin;
     35  const char16ptr_t mCommandMac;
     36  const char16ptr_t mCommandLinux;
     37  const char16ptr_t mCommandAndroid;
     38  const char16ptr_t mCommandEmacs;
     39 };
     40 
     41 #if defined(XP_WIN)
     42 #  define GetCommandForPlatform(aMap) aMap.mCommandWin
     43 #elif defined(MOZ_WIDGET_COCOA)
     44 #  define GetCommandForPlatform(aMap) aMap.mCommandMac
     45 #elif defined(MOZ_WIDGET_GTK)
     46 #  define GetCommandForPlatform(aMap) aMap.mCommandLinux
     47 #elif defined(MOZ_WIDGET_ANDROID)
     48 #  define GetCommandForPlatform(aMap) aMap.mCommandAndroid
     49 #else
     50 #  define GetCommandForPlatform(aMap) aMap.mCommandEmacs
     51 #endif
     52 
     53 static bool GetCommandFor(KeyEventHandler* aFirstHandler,
     54                          dom::KeyboardEvent* aDOMEvent, nsAString& aCommand) {
     55  if (!aFirstHandler) {
     56    return false;
     57  }
     58  aCommand.Truncate();
     59  for (KeyEventHandler* handler = aFirstHandler; handler;
     60       handler = handler->GetNextHandler()) {
     61    if (handler->KeyEventMatched(aDOMEvent, 0, IgnoreModifierState())) {
     62      handler->GetCommand(aCommand);
     63      return true;
     64    }
     65  }
     66  return false;
     67 }
     68 
     69 static char16ptr_t GetExpectedCommandFor(
     70    const nsTArray<ShortcutKeyMap>& aExpectedMap,
     71    const WidgetKeyboardEvent& aWidgetEvent) {
     72  MOZ_ASSERT(!aExpectedMap.IsEmpty());
     73  for (const ShortcutKeyMap& map : aExpectedMap) {
     74    if (aWidgetEvent.mKeyCode == map.mKeyCode &&
     75        aWidgetEvent.mCharCode == map.mCharCode &&
     76        aWidgetEvent.mModifiers == map.mModifiers) {
     77      return GetCommandForPlatform(map);
     78    }
     79  }
     80  return nullptr;
     81 }
     82 
     83 struct KeyCodeAndStr final {
     84  uint32_t mKeyCode;
     85  KeyNameIndex mKeyNameIndex;
     86  const char* mStr;
     87 };
     88 static const KeyCodeAndStr kKeyCodes[] = {
     89    {NS_VK_BACK, KEY_NAME_INDEX_Backspace, "Backspace"},
     90    {NS_VK_RETURN, KEY_NAME_INDEX_Enter, "Enter"},
     91    {NS_VK_ESCAPE, KEY_NAME_INDEX_Escape, "Escape"},
     92    {NS_VK_PAGE_UP, KEY_NAME_INDEX_PageUp, "PageUp"},
     93    {NS_VK_PAGE_DOWN, KEY_NAME_INDEX_PageDown, "PageDown"},
     94    {NS_VK_END, KEY_NAME_INDEX_End, "End"},
     95    {NS_VK_HOME, KEY_NAME_INDEX_Home, "Home"},
     96    {NS_VK_LEFT, KEY_NAME_INDEX_ArrowLeft, "ArrowLeft"},
     97    {NS_VK_UP, KEY_NAME_INDEX_ArrowUp, "ArrowUp"},
     98    {NS_VK_RIGHT, KEY_NAME_INDEX_ArrowRight, "ArrowRight"},
     99    {NS_VK_DOWN, KEY_NAME_INDEX_ArrowDown, "ArrowDown"},
    100 #ifndef MOZ_WIDGET_COCOA
    101    // No Insert key on macOS
    102    {NS_VK_INSERT, KEY_NAME_INDEX_Insert, "Insert"},
    103 #endif
    104    {NS_VK_DELETE, KEY_NAME_INDEX_Delete, "Delete"},
    105    {NS_VK_F1, KEY_NAME_INDEX_F1, "F1"},
    106    {NS_VK_F2, KEY_NAME_INDEX_F2, "F2"},
    107    {NS_VK_F3, KEY_NAME_INDEX_F3, "F3"},
    108    {NS_VK_F4, KEY_NAME_INDEX_F4, "F4"},
    109    {NS_VK_F5, KEY_NAME_INDEX_F5, "F5"},
    110    {NS_VK_F6, KEY_NAME_INDEX_F6, "F6"},
    111    {NS_VK_F7, KEY_NAME_INDEX_F7, "F7"},
    112    {NS_VK_F8, KEY_NAME_INDEX_F8, "F8"},
    113    {NS_VK_F9, KEY_NAME_INDEX_F9, "F9"},
    114    {NS_VK_F10, KEY_NAME_INDEX_F10, "F10"},
    115    {NS_VK_F11, KEY_NAME_INDEX_F11, "F11"},
    116    {NS_VK_F12, KEY_NAME_INDEX_F12, "F12"},
    117 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID)
    118    {NS_VK_F13, KEY_NAME_INDEX_F13, "F13"},
    119    {NS_VK_F14, KEY_NAME_INDEX_F14, "F14"},
    120    {NS_VK_F15, KEY_NAME_INDEX_F15, "F15"},
    121    {NS_VK_F16, KEY_NAME_INDEX_F16, "F16"},
    122    {NS_VK_F17, KEY_NAME_INDEX_F17, "F17"},
    123    {NS_VK_F18, KEY_NAME_INDEX_F18, "F18"},
    124    {NS_VK_F19, KEY_NAME_INDEX_F19, "F19"},
    125 #endif
    126 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    127    {NS_VK_F20, KEY_NAME_INDEX_F20, "F20"},
    128    {NS_VK_F21, KEY_NAME_INDEX_F21, "F21"},
    129    {NS_VK_F22, KEY_NAME_INDEX_F22, "F22"},
    130    {NS_VK_F23, KEY_NAME_INDEX_F23, "F23"},
    131    {NS_VK_F24, KEY_NAME_INDEX_F24, "F24"},
    132 #endif
    133 };
    134 
    135 static const unsigned char kCharCodes[] = {
    136    ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
    137    'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
    138    'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    139 
    140 struct ModifiersAndStr final {
    141  Modifiers mModifiers;
    142  const char* mStr;
    143 };
    144 static const ModifiersAndStr kModifiers[] = {
    145    {MODIFIER_NONE, ""},
    146    {MODIFIER_SHIFT, "Shift+"},
    147    {MODIFIER_CONTROL, "Control+"},
    148    {MODIFIER_CONTROL | MODIFIER_SHIFT, "Contrl+Shift+"},
    149    {MODIFIER_ALT, "Alt+"},
    150    {MODIFIER_ALT | MODIFIER_SHIFT, "Alt+Shift+"},
    151    {MODIFIER_META, "Meta+"},
    152    {MODIFIER_META | MODIFIER_SHIFT, "Meta+Shift+"},
    153    {MODIFIER_META | MODIFIER_ALT | MODIFIER_SHIFT, "Meta+Alt+Shift+"},
    154    {MODIFIER_CONTROL | MODIFIER_ALT, "Control+Alt+"},
    155    {MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_SHIFT, "Control+Alt+Shift+"},
    156 };
    157 
    158 static void TestAllKeyCodes(KeyEventHandler* aFirstHandler,
    159                            const nsTArray<ShortcutKeyMap>& aExpectedMap) {
    160  WidgetKeyboardEvent widgetEvent(true, eKeyPress, nullptr);
    161  RefPtr<dom::KeyboardEvent> domEvent =
    162      NS_NewDOMKeyboardEvent(nullptr, nullptr, &widgetEvent);
    163  nsAutoString command;
    164  uint32_t foundCommand = 0;
    165  for (const auto& mod : kModifiers) {
    166    widgetEvent.mModifiers = mod.mModifiers;
    167    for (const auto& keyCode : kKeyCodes) {
    168      widgetEvent.mKeyCode = keyCode.mKeyCode;
    169      widgetEvent.mKeyNameIndex = keyCode.mKeyNameIndex;
    170      const char16ptr_t expectedCommand =
    171          GetExpectedCommandFor(aExpectedMap, widgetEvent);
    172      if (GetCommandFor(aFirstHandler, domEvent, command)) {
    173        foundCommand++;
    174        if (expectedCommand) {
    175          ASSERT_TRUE(command.Equals(expectedCommand))
    176          << mod.mStr << keyCode.mStr << ": got "
    177          << NS_ConvertUTF16toUTF8(command).get() << ", but expected "
    178          << NS_ConvertUTF16toUTF8(expectedCommand).get();
    179        } else {
    180          ASSERT_TRUE(false)
    181          << mod.mStr << keyCode.mStr << ": got "
    182          << NS_ConvertUTF16toUTF8(command).get()
    183          << ", but expected no command";
    184        }
    185      } else if (expectedCommand) {
    186        ASSERT_TRUE(false)
    187        << mod.mStr << keyCode.mStr << ": got no command, but expected "
    188        << NS_ConvertUTF16toUTF8(expectedCommand).get();
    189      }
    190    }
    191    widgetEvent.mKeyCode = 0;
    192    widgetEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
    193    for (unsigned char charCode : kCharCodes) {
    194      widgetEvent.mCharCode = charCode;
    195      widgetEvent.mKeyValue.Assign(charCode);
    196      const char16ptr_t expectedCommand =
    197          GetExpectedCommandFor(aExpectedMap, widgetEvent);
    198      if (GetCommandFor(aFirstHandler, domEvent, command)) {
    199        foundCommand++;
    200        if (expectedCommand) {
    201          ASSERT_TRUE(command.Equals(expectedCommand))
    202          << mod.mStr << "'" << nsAutoCString(charCode).get() << "': got "
    203          << NS_ConvertUTF16toUTF8(command).get() << ", but expected "
    204          << NS_ConvertUTF16toUTF8(expectedCommand).get();
    205        } else {
    206          ASSERT_TRUE(false)
    207          << mod.mStr << "'" << nsAutoCString(charCode).get() << "': got "
    208          << NS_ConvertUTF16toUTF8(command).get()
    209          << ", but expected no command";
    210        }
    211      } else if (expectedCommand) {
    212        ASSERT_TRUE(false)
    213        << mod.mStr << "'" << nsAutoCString(charCode).get()
    214        << "': got no command, but expected "
    215        << NS_ConvertUTF16toUTF8(expectedCommand).get();
    216      }
    217    }
    218    widgetEvent.mCharCode = 0;
    219    widgetEvent.mKeyValue.Truncate();
    220  }
    221  uint32_t expectedCommandCount = 0;
    222  for (const auto& map : aExpectedMap) {
    223    if (GetCommandForPlatform(map)) {
    224      expectedCommandCount++;
    225    }
    226  }
    227  ASSERT_EQ(foundCommand, expectedCommandCount)
    228      << "Some expected shortcut keys have not been tested";
    229  uint32_t countOfHandler = 0;
    230  for (KeyEventHandler* handler = aFirstHandler; handler;
    231       handler = handler->GetNextHandler()) {
    232    countOfHandler++;
    233  }
    234  ASSERT_EQ(countOfHandler, expectedCommandCount)
    235      << "Some unnecessary key handlers found";
    236 }
    237 
    238 TEST(ShortcutKeyDefinitions, HTMLInputElement)
    239 {
    240  // clang-format off
    241  const nsTArray<ShortcutKeyMap> expectedMap{
    242    // KeyCode       Modifiers         Windows             macOS    Linux               Android              Emacs
    243    {NS_VK_LEFT,  0, MODIFIER_NONE,    u"cmd_moveLeft",    nullptr, u"cmd_moveLeft",    u"cmd_moveLeft",     u"cmd_moveLeft"},
    244    {NS_VK_RIGHT, 0, MODIFIER_NONE,    u"cmd_moveRight",   nullptr, u"cmd_moveRight",   u"cmd_moveRight",    u"cmd_moveRight"},
    245    {NS_VK_LEFT,  0, MODIFIER_SHIFT,   u"cmd_selectLeft",  nullptr, u"cmd_selectLeft",  u"cmd_selectLeft",   u"cmd_selectLeft"},
    246    {NS_VK_RIGHT, 0, MODIFIER_SHIFT,   u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight",  u"cmd_selectRight"},
    247    {NS_VK_LEFT,  0, MODIFIER_CONTROL, u"cmd_moveLeft2",   nullptr, nullptr,            u"cmd_wordPrevious", u"cmd_wordPrevious"},
    248    {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2",  nullptr, nullptr,            u"cmd_wordNext",     u"cmd_wordNext"},
    249    {NS_VK_LEFT,  0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_beginLine",    nullptr},
    250    {NS_VK_RIGHT, 0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_endLine",      nullptr},
    251    {NS_VK_UP,    0, MODIFIER_NONE,    u"cmd_moveUp",      nullptr, u"cmd_moveUp",      u"cmd_moveUp",       u"cmd_moveUp"},
    252    {NS_VK_DOWN,  0, MODIFIER_NONE,    u"cmd_moveDown",    nullptr, u"cmd_moveDown",    u"cmd_moveDown",     u"cmd_moveDown"},
    253    {NS_VK_UP,    0, MODIFIER_SHIFT,   u"cmd_selectUp",    nullptr, u"cmd_selectUp",    u"cmd_selectUp",     u"cmd_selectUp"},
    254    {NS_VK_DOWN,  0, MODIFIER_SHIFT,   u"cmd_selectDown",  nullptr, u"cmd_selectDown",  u"cmd_selectDown",   u"cmd_selectDown"},
    255    {NS_VK_UP,    0, MODIFIER_CONTROL, u"cmd_moveUp2",     nullptr, nullptr,            nullptr,             nullptr},
    256    {NS_VK_DOWN,  0, MODIFIER_CONTROL, u"cmd_moveDown2",   nullptr, nullptr,            nullptr,             nullptr},
    257 
    258    // KeyCode       Modifiers                          Windows              macOS    Linux    Android                    Emacs
    259    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2",  nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"},
    260    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext",     u"cmd_selectWordNext"},
    261    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectBeginLine",    nullptr},
    262    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectEndLine",      nullptr},
    263    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2",    nullptr, nullptr, nullptr,                   nullptr},
    264    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2",  nullptr, nullptr, nullptr,                   nullptr},
    265 
    266    // KeyCode       Modifiers         Windows                 macOS    Linux    Android                 Emacs
    267    {NS_VK_HOME,  0, MODIFIER_NONE,    u"cmd_beginLine",       nullptr, nullptr, u"cmd_beginLine",       u"cmd_beginLine"},
    268    {NS_VK_END,   0, MODIFIER_NONE,    u"cmd_endLine",         nullptr, nullptr, u"cmd_endLine",         u"cmd_endLine"},
    269    {NS_VK_HOME,  0, MODIFIER_SHIFT,   u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"},
    270    {NS_VK_END,   0, MODIFIER_SHIFT,   u"cmd_selectEndLine",   nullptr, nullptr, u"cmd_selectEndLine",   u"cmd_selectEndLine"},
    271    {NS_VK_HOME,  0, MODIFIER_CONTROL, u"cmd_moveTop",         nullptr, nullptr, nullptr,                u"cmd_beginLine"},
    272    {NS_VK_END,   0, MODIFIER_CONTROL, u"cmd_moveBottom",      nullptr, nullptr, nullptr,                u"cmd_endLine"},
    273 
    274    // KeyCode       Modifiers                          Windows              macOS    Linux    Android  Emacs
    275    {NS_VK_HOME,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop",    nullptr, nullptr, nullptr, u"cmd_selectBeginLine"},
    276    {NS_VK_END,   0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, nullptr, u"cmd_selectEndLine"},
    277 
    278    // KeyCode         Modifiers         Windows                    macOS    Linux    Android
    279    {NS_VK_INSERT,  0, MODIFIER_SHIFT,   u"cmd_paste",              nullptr, nullptr, nullptr,                        u"cmd_paste"},
    280    {NS_VK_INSERT,  0, MODIFIER_CONTROL, u"cmd_copy",               nullptr, nullptr, nullptr,                        u"cmd_copy"},
    281    {NS_VK_DELETE,  0, MODIFIER_SHIFT,   u"cmd_cutOrDelete",        nullptr, nullptr, nullptr,                        u"cmd_cutOrDelete"},
    282    {NS_VK_DELETE,  0, MODIFIER_CONTROL, u"cmd_deleteWordForward",  nullptr, nullptr, u"cmd_deleteWordForward",       u"cmd_copyOrDelete"},
    283    {NS_VK_DELETE,  0, MODIFIER_ALT,     nullptr,                   nullptr, nullptr, u"cmd_deleteToEndOfLine",       nullptr},
    284    {NS_VK_BACK,    0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward",      u"cmd_deleteWordBackward"},
    285    {NS_VK_BACK,    0, MODIFIER_ALT,     u"cmd_undo",               nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr},
    286 
    287    // KeyCode      Modifiers                      Windows      macOS    Linux    Android  Emacs
    288    {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr},
    289 
    290    // charCode Modifiers,      Windows           macOS             Linux             Android           Emacs
    291    {0, 'a',    MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", nullptr},
    292    {0, 'a',    MODIFIER_ALT,   nullptr,          nullptr,          nullptr,          nullptr,          u"cmd_selectAll"},
    293    {0, 'c',    MODIFIER_ACCEL, u"cmd_copy",      u"cmd_copy",      u"cmd_copy",      u"cmd_copy",      u"cmd_copy"},
    294    {0, 'x',    MODIFIER_ACCEL, u"cmd_cut",       u"cmd_cut",       u"cmd_cut",       u"cmd_cut",       u"cmd_cut"},
    295    {0, 'v',    MODIFIER_ACCEL, u"cmd_paste",     u"cmd_paste",     u"cmd_paste",     u"cmd_paste",     u"cmd_paste"},
    296    {0, 'y',    MODIFIER_ACCEL, u"cmd_redo",      nullptr,          u"cmd_redo",      nullptr,          u"cmd_redo"},
    297    {0, 'z',    MODIFIER_ACCEL, u"cmd_undo",      u"cmd_undo",      u"cmd_undo",      u"cmd_undo",      u"cmd_undo"},
    298 
    299    // charCode Modifiers,                                      Windows       macOS         Linux         Android       Emacs
    300    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ACCEL,                u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"},
    301    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr,      u"cmd_paste", nullptr,      nullptr,      nullptr},
    302 
    303    // charCode Modifiers                        Windows      macOS        Linux        Android      Emacs
    304    {0, 'z',    MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"},
    305 
    306    // charCode Modifiers         Windows  macOS    Linux    Android  Emacs
    307    {0, 'a',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"},
    308    {0, 'b',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"},
    309    {0, 'd',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"},
    310    {0, 'e',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"},
    311    {0, 'f',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"},
    312    {0, 'h',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"},
    313    {0, 'k',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"},
    314    {0, 'u',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"},
    315    {0, 'w',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"},
    316  };
    317  // clang-format on
    318 
    319  TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eInput), expectedMap);
    320 
    321  ShortcutKeys::Shutdown();  // Destroy the singleton instance.
    322 }
    323 
    324 TEST(ShortcutKeyDefinitions, HTMLTextAreaElement)
    325 {
    326  // clang-format off
    327  const nsTArray<ShortcutKeyMap> expectedMap{
    328    // KeyCode       Modifiers         Windows             macOS    Linux               Android              Emacs
    329    {NS_VK_LEFT,  0, MODIFIER_NONE,    u"cmd_moveLeft",    nullptr, u"cmd_moveLeft",    u"cmd_moveLeft",     u"cmd_moveLeft"},
    330    {NS_VK_RIGHT, 0, MODIFIER_NONE,    u"cmd_moveRight",   nullptr, u"cmd_moveRight",   u"cmd_moveRight",    u"cmd_moveRight"},
    331    {NS_VK_LEFT,  0, MODIFIER_SHIFT,   u"cmd_selectLeft",  nullptr, u"cmd_selectLeft",  u"cmd_selectLeft",   u"cmd_selectLeft"},
    332    {NS_VK_RIGHT, 0, MODIFIER_SHIFT,   u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight",  u"cmd_selectRight"},
    333    {NS_VK_LEFT,  0, MODIFIER_CONTROL, u"cmd_moveLeft2",   nullptr, nullptr,            u"cmd_wordPrevious", u"cmd_wordPrevious"},
    334    {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2",  nullptr, nullptr,            u"cmd_wordNext",     u"cmd_wordNext"},
    335    {NS_VK_LEFT,  0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_beginLine",    nullptr},
    336    {NS_VK_RIGHT, 0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_endLine",      nullptr},
    337    {NS_VK_UP,    0, MODIFIER_NONE,    u"cmd_moveUp",      nullptr, u"cmd_moveUp",      u"cmd_moveUp",       u"cmd_moveUp"},
    338    {NS_VK_DOWN,  0, MODIFIER_NONE,    u"cmd_moveDown",    nullptr, u"cmd_moveDown",    u"cmd_moveDown",     u"cmd_moveDown"},
    339    {NS_VK_UP,    0, MODIFIER_SHIFT,   u"cmd_selectUp",    nullptr, u"cmd_selectUp",    u"cmd_selectUp",     u"cmd_selectUp"},
    340    {NS_VK_DOWN,  0, MODIFIER_SHIFT,   u"cmd_selectDown",  nullptr, u"cmd_selectDown",  u"cmd_selectDown",   u"cmd_selectDown"},
    341    {NS_VK_UP,    0, MODIFIER_CONTROL, u"cmd_moveUp2",     nullptr, nullptr,            nullptr,             nullptr},
    342    {NS_VK_DOWN,  0, MODIFIER_CONTROL, u"cmd_moveDown2",   nullptr, nullptr,            nullptr,             nullptr},
    343    {NS_VK_UP,    0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_moveTop",      nullptr},
    344    {NS_VK_DOWN,  0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_moveBottom",   nullptr},
    345 
    346    // KeyCode       Modifiers                          Windows              macOS    Linux    Android                    Emacs
    347    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2",  nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"},
    348    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext",     u"cmd_selectWordNext"},
    349    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectBeginLine",    nullptr},
    350    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectEndLine",      nullptr},
    351    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2",    nullptr, nullptr, nullptr,                   nullptr},
    352    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2",  nullptr, nullptr, nullptr,                   nullptr},
    353    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectTop",          nullptr},
    354    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectBottom",       nullptr},
    355 
    356    // KeyCode           Modifiers       Windows                macOS    Linux    Android                Emacs
    357    {NS_VK_PAGE_UP,   0, MODIFIER_NONE,  u"cmd_movePageUp",     nullptr, nullptr, u"cmd_movePageUp",     u"cmd_movePageUp"},
    358    {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE,  u"cmd_movePageDown",   nullptr, nullptr, u"cmd_movePageDown",   u"cmd_movePageDown"},
    359    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT, u"cmd_selectPageUp",   nullptr, nullptr, u"cmd_selectPageUp",   u"cmd_selectPageUp"},
    360    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr, nullptr, u"cmd_selectPageDown", u"cmd_selectPageDown"},
    361    {NS_VK_PAGE_UP,   0, MODIFIER_ALT,   nullptr,               nullptr, nullptr, u"cmd_moveTop",        nullptr},
    362    {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT,   nullptr,               nullptr, nullptr, u"cmd_moveBottom",     nullptr},
    363 
    364    // KeyCode           Modifiers                        Windows  macOS    Linux    Android              Emacs
    365    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectTop",    nullptr},
    366    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr},
    367 
    368    // KeyCode       Modifiers         Windows                 macOS    Linux    Android                 Emacs
    369    {NS_VK_HOME,  0, MODIFIER_NONE,    u"cmd_beginLine",       nullptr, nullptr, u"cmd_beginLine",       u"cmd_beginLine"},
    370    {NS_VK_END,   0, MODIFIER_NONE,    u"cmd_endLine",         nullptr, nullptr, u"cmd_endLine",         u"cmd_endLine"},
    371    {NS_VK_HOME,  0, MODIFIER_SHIFT,   u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"},
    372    {NS_VK_END,   0, MODIFIER_SHIFT,   u"cmd_selectEndLine",   nullptr, nullptr, u"cmd_selectEndLine",   u"cmd_selectEndLine"},
    373    {NS_VK_HOME,  0, MODIFIER_CONTROL, u"cmd_moveTop",         nullptr, nullptr, u"cmd_moveTop",         u"cmd_moveTop"},
    374    {NS_VK_END,   0, MODIFIER_CONTROL, u"cmd_moveBottom",      nullptr, nullptr, u"cmd_moveBottom",      u"cmd_moveBottom"},
    375 
    376    // KeyCode       Modifiers                          Windows              macOS    Linux    Android              Emacs
    377    {NS_VK_HOME,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop",    nullptr, nullptr, u"cmd_selectTop",    u"cmd_selectTop"},
    378    {NS_VK_END,   0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, u"cmd_selectBottom", u"cmd_selectBottom"},
    379 
    380    // KeyCode         Modifiers         Windows                    macOS    Linux    Android                         Emacs
    381    {NS_VK_INSERT,  0, MODIFIER_SHIFT,   u"cmd_paste",              nullptr, nullptr, nullptr,                        u"cmd_paste"},
    382    {NS_VK_INSERT,  0, MODIFIER_CONTROL, u"cmd_copy",               nullptr, nullptr, nullptr,                        u"cmd_copy"},
    383    {NS_VK_DELETE,  0, MODIFIER_SHIFT,   u"cmd_cutOrDelete",        nullptr, nullptr, nullptr,                        u"cmd_cutOrDelete"},
    384    {NS_VK_DELETE,  0, MODIFIER_CONTROL, u"cmd_deleteWordForward",  nullptr, nullptr, u"cmd_deleteWordForward",       u"cmd_copyOrDelete"},
    385    {NS_VK_DELETE,  0, MODIFIER_ALT,     nullptr,                   nullptr, nullptr, u"cmd_deleteToEndOfLine",       nullptr},
    386    {NS_VK_BACK,    0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward",      u"cmd_deleteWordBackward"},
    387    {NS_VK_BACK,    0, MODIFIER_ALT,     u"cmd_undo",               nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr},
    388 
    389    // KeyCode      Modifiers                      Windows      macOS    Linux    Android  Emacs
    390    {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr},
    391 
    392    // charCode Modifiers,      Windows           macOS             Linux             Android           Emacs
    393    {0, 'a',    MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", nullptr},
    394    {0, 'a',    MODIFIER_ALT,   nullptr,          nullptr,          nullptr,          nullptr,          u"cmd_selectAll"},
    395    {0, 'c',    MODIFIER_ACCEL, u"cmd_copy",      u"cmd_copy",      u"cmd_copy",      u"cmd_copy",      u"cmd_copy"},
    396    {0, 'x',    MODIFIER_ACCEL, u"cmd_cut",       u"cmd_cut",       u"cmd_cut",       u"cmd_cut",       u"cmd_cut"},
    397    {0, 'v',    MODIFIER_ACCEL, u"cmd_paste",     u"cmd_paste",     u"cmd_paste",     u"cmd_paste",     u"cmd_paste"},
    398    {0, 'y',    MODIFIER_ACCEL, u"cmd_redo",      nullptr,          u"cmd_redo",      nullptr,          u"cmd_redo"},
    399    {0, 'z',    MODIFIER_ACCEL, u"cmd_undo",      u"cmd_undo",      u"cmd_undo",      u"cmd_undo",      u"cmd_undo"},
    400 
    401    // charCode Modifiers,                                      Windows       macOS         Linux         Android       Emacs
    402    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ACCEL,                u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"},
    403    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr,      u"cmd_paste", nullptr,      nullptr,      nullptr},
    404 
    405    // charCode Modifiers                        Windows      macOS        Linux        Android      Emacs
    406    {0, 'z',    MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"},
    407 
    408    // charCode Modifiers         Windows  macOS    Linux    Android  Emacs
    409    {0, 'a',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"},
    410    {0, 'b',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"},
    411    {0, 'd',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"},
    412    {0, 'e',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"},
    413    {0, 'f',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"},
    414    {0, 'h',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"},
    415    {0, 'k',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"},
    416    {0, 'n',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_lineNext"},
    417    {0, 'p',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_linePrevious"},
    418    {0, 'u',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"},
    419    {0, 'w',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"},
    420  };
    421  // clang-format on
    422 
    423  TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eTextArea),
    424                  expectedMap);
    425 
    426  ShortcutKeys::Shutdown();  // Destroy the singleton instance.
    427 }
    428 
    429 TEST(ShortcutKeyDefinitions, Browser)
    430 {
    431  // clang-format off
    432  const nsTArray<ShortcutKeyMap> expectedMap{
    433    // KeyCode       Modifiers         Windows             macOS               Linux               Android                    Emacs
    434    {NS_VK_LEFT,  0, MODIFIER_NONE,    u"cmd_moveLeft",    u"cmd_moveLeft",    u"cmd_moveLeft",    u"cmd_moveLeft",           u"cmd_moveLeft"},
    435    {NS_VK_RIGHT, 0, MODIFIER_NONE,    u"cmd_moveRight",   u"cmd_moveRight",   u"cmd_moveRight",   u"cmd_moveRight",          u"cmd_moveRight"},
    436    {NS_VK_LEFT,  0, MODIFIER_SHIFT,   u"cmd_selectLeft",  u"cmd_selectLeft",  u"cmd_selectLeft",  u"cmd_selectCharPrevious", u"cmd_selectLeft"},
    437    {NS_VK_RIGHT, 0, MODIFIER_SHIFT,   u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectCharNext",     u"cmd_selectRight"},
    438    {NS_VK_LEFT,  0, MODIFIER_CONTROL, u"cmd_moveLeft2",   nullptr,            u"cmd_moveLeft2",   u"cmd_wordPrevious",       u"cmd_wordPrevious"},
    439    {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2",  nullptr,            u"cmd_moveRight2",  u"cmd_wordNext",           u"cmd_wordNext"},
    440    {NS_VK_LEFT,  0, MODIFIER_ALT,     nullptr,            u"cmd_moveLeft2",   nullptr,            u"cmd_beginLine",          nullptr},
    441    {NS_VK_RIGHT, 0, MODIFIER_ALT,     nullptr,            u"cmd_moveRight2",  nullptr,            u"cmd_endLine",            nullptr},
    442    {NS_VK_UP,    0, MODIFIER_NONE,    u"cmd_moveUp",      u"cmd_moveUp",      u"cmd_moveUp",      u"cmd_moveUp",             u"cmd_moveUp"},
    443    {NS_VK_DOWN,  0, MODIFIER_NONE,    u"cmd_moveDown",    u"cmd_moveDown",    u"cmd_moveDown",    u"cmd_moveDown",           u"cmd_moveDown"},
    444    {NS_VK_UP,    0, MODIFIER_SHIFT,   u"cmd_selectUp",    u"cmd_selectUp",    u"cmd_selectUp",    u"cmd_selectLinePrevious", u"cmd_selectUp"},
    445    {NS_VK_DOWN,  0, MODIFIER_SHIFT,   u"cmd_selectDown",  u"cmd_selectDown",  u"cmd_selectDown",  u"cmd_selectLineNext",     u"cmd_selectDown"},
    446    {NS_VK_UP,    0, MODIFIER_CONTROL, u"cmd_moveUp2",     nullptr,            u"cmd_moveUp2",     nullptr,                   nullptr},
    447    {NS_VK_DOWN,  0, MODIFIER_CONTROL, u"cmd_moveDown2",   nullptr,            u"cmd_moveDown2",   nullptr,                   nullptr},
    448    {NS_VK_UP,    0, MODIFIER_ALT,     nullptr,            nullptr,            nullptr,            u"cmd_moveTop",            nullptr},
    449    {NS_VK_DOWN,  0, MODIFIER_ALT,     nullptr,            nullptr,            nullptr,            u"cmd_moveBottom",         nullptr},
    450    {NS_VK_UP,    0, MODIFIER_META,    nullptr,            u"cmd_moveUp2",     nullptr,            nullptr,                   nullptr},
    451    {NS_VK_DOWN,  0, MODIFIER_META,    nullptr,            u"cmd_moveDown2",   nullptr,            nullptr,                   nullptr},
    452 
    453    // KeyCode       Modifiers                          Windows              macOS                Linux                Android                    Emacs
    454    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2",  nullptr,             u"cmd_selectLeft2",  u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"},
    455    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr,             u"cmd_selectRight2", u"cmd_selectWordNext",     u"cmd_selectWordNext"},
    456    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             u"cmd_selectLeft2",  nullptr,             u"cmd_selectBeginLine",    nullptr},
    457    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             u"cmd_selectRight2", nullptr,             u"cmd_selectEndLine",      nullptr},
    458    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2",    nullptr,             u"cmd_selectUp2",    nullptr,                   u"cmd_selectWordPrevious"},
    459    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2",  nullptr,             u"cmd_selectDown2",  nullptr,                   u"cmd_selectWordNext"},
    460    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             u"cmd_selectUp2",    nullptr,             u"cmd_selectTop",          nullptr},
    461    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             u"cmd_selectDown2",  nullptr,             u"cmd_selectBottom",       nullptr},
    462 
    463    // KeyCode           Modifiers       Windows                macOS                  Linux                  Android                Emacs
    464    {NS_VK_PAGE_UP,   0, MODIFIER_NONE,  u"cmd_movePageUp",     u"cmd_scrollPageUp",   u"cmd_movePageUp",     u"cmd_movePageUp",     u"cmd_movePageUp"},
    465    {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE,  u"cmd_movePageDown",   u"cmd_scrollPageDown", u"cmd_movePageDown",   u"cmd_movePageDown",   u"cmd_movePageDown"},
    466    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT, u"cmd_selectPageUp",   nullptr,               u"cmd_selectPageUp",   u"cmd_selectPageUp",   u"cmd_selectPageUp"},
    467    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr,               u"cmd_selectPageDown", u"cmd_selectPageDown", u"cmd_selectPageDown"},
    468    {NS_VK_PAGE_UP,   0, MODIFIER_ALT,   nullptr,               nullptr,               nullptr,               u"cmd_moveTop",        nullptr},
    469    {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT,   nullptr,               nullptr,               nullptr,               u"cmd_moveBottom",     nullptr},
    470 
    471    // KeyCode           Modifiers                        Windows  macOS    Linux    Android              Emacs
    472    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectTop",    nullptr},
    473    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr},
    474 
    475    // KeyCode       Modifiers         Windows                 macOS                Linux                   Android                 Emacs
    476    {NS_VK_HOME,  0, MODIFIER_NONE,    u"cmd_beginLine",       u"cmd_scrollTop",    u"cmd_beginLine",       u"cmd_beginLine",       u"cmd_beginLine"},
    477    {NS_VK_END,   0, MODIFIER_NONE,    u"cmd_endLine",         u"cmd_scrollBottom", u"cmd_endLine",         u"cmd_endLine",         u"cmd_endLine"},
    478    {NS_VK_HOME,  0, MODIFIER_SHIFT,   u"cmd_selectBeginLine", nullptr,             u"cmd_selectBeginLine", u"cmd_selectBeginLine", u"cmd_selectBeginLine"},
    479    {NS_VK_END,   0, MODIFIER_SHIFT,   u"cmd_selectEndLine",   nullptr,             u"cmd_selectEndLine",   u"cmd_selectEndLine",   u"cmd_selectEndLine"},
    480    {NS_VK_HOME,  0, MODIFIER_CONTROL, u"cmd_moveTop",         nullptr,             u"cmd_moveTop",         u"cmd_moveTop",         u"cmd_moveTop"},
    481    {NS_VK_END,   0, MODIFIER_CONTROL, u"cmd_moveBottom",      nullptr,             u"cmd_moveBottom",      u"cmd_moveBottom",      u"cmd_moveBottom"},
    482 
    483    // KeyCode       Modifiers                          Windows              macOS    Linux                Android              Emacs
    484    {NS_VK_HOME,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop",    nullptr, u"cmd_selectTop",    u"cmd_selectTop",    u"cmd_selectTop"},
    485    {NS_VK_END,   0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, u"cmd_selectBottom", u"cmd_selectBottom", u"cmd_selectBottom"},
    486 
    487    // KeyCode         Modifiers         Windows                    macOS    Linux        Android                         Emacs
    488    {NS_VK_INSERT,  0, MODIFIER_CONTROL, u"cmd_copy",               nullptr, u"cmd_copy", nullptr,                        u"cmd_copy"},
    489    {NS_VK_DELETE,  0, MODIFIER_SHIFT,   u"cmd_cut",                nullptr, u"cmd_cut",  nullptr,                        u"cmd_cut"},
    490    {NS_VK_DELETE,  0, MODIFIER_CONTROL, u"cmd_deleteWordForward",  nullptr, u"cmd_copy", u"cmd_deleteWordForward",       u"cmd_copy"},
    491    {NS_VK_DELETE,  0, MODIFIER_ALT,     nullptr,                   nullptr, nullptr,     u"cmd_deleteToEndOfLine",       nullptr},
    492    {NS_VK_BACK,    0, MODIFIER_CONTROL, nullptr,                   nullptr, nullptr,     u"cmd_deleteWordBackward",      nullptr},
    493    {NS_VK_BACK,    0, MODIFIER_ALT,     nullptr,                   nullptr, nullptr,     u"cmd_deleteToBeginningOfLine", nullptr},
    494 
    495    // charCode Modifiers,      Windows                macOS                  Linux                  Android                Emacs
    496    {0, ' ',    MODIFIER_NONE,  u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown"},
    497    {0, ' ',    MODIFIER_SHIFT, u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp"},
    498    {0, 'a',    MODIFIER_ACCEL, u"cmd_selectAll",      u"cmd_selectAll",      u"cmd_selectAll",      u"cmd_selectAll",      u"cmd_selectAll"},
    499    {0, 'a',    MODIFIER_ALT,   nullptr,               nullptr,               nullptr,               nullptr,               u"cmd_selectAll"},
    500    {0, 'c',    MODIFIER_ACCEL, u"cmd_copy",           u"cmd_copy",           u"cmd_copy",           u"cmd_copy",           u"cmd_copy"},
    501    {0, 'x',    MODIFIER_ACCEL, u"cmd_cut",            u"cmd_cut",            u"cmd_cut",            u"cmd_cut",            u"cmd_cut"},
    502    {0, 'v',    MODIFIER_ACCEL, u"cmd_paste",          u"cmd_paste",          u"cmd_paste",          u"cmd_paste",          u"cmd_paste"},
    503    {0, 'y',    MODIFIER_ACCEL, u"cmd_redo",           nullptr,               nullptr,               nullptr,               nullptr},
    504    {0, 'z',    MODIFIER_ACCEL, u"cmd_undo",           u"cmd_undo",           u"cmd_undo",           u"cmd_undo",           u"cmd_undo"},
    505 
    506    // charCode Modifiers,                                      Windows       macOS         Linux         Android       Emacs
    507    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ACCEL,                u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting"},
    508 
    509    // charCode Modifiers,                                      Windows  macOS                     Linux    Android  Emacs
    510    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr, u"cmd_pasteNoFormatting", nullptr, nullptr, nullptr},
    511 
    512    // charCode Modifiers                        Windows      macOS        Linux        Android      Emacs
    513    {0, 'z',    MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"},
    514  };
    515  // clang-format on
    516 
    517  TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eBrowser),
    518                  expectedMap);
    519 
    520  ShortcutKeys::Shutdown();  // Destroy the singleton instance.
    521 }
    522 
    523 TEST(ShortcutKeyDefinitions, HTMLEditor)
    524 {
    525  // clang-format off
    526  const nsTArray<ShortcutKeyMap> expectedMap{
    527    // KeyCode       Modifiers         Windows             macOS    Linux               Android              Emacs
    528    {NS_VK_LEFT,  0, MODIFIER_NONE,    u"cmd_moveLeft",    nullptr, u"cmd_moveLeft",    u"cmd_moveLeft",     u"cmd_moveLeft"},
    529    {NS_VK_RIGHT, 0, MODIFIER_NONE,    u"cmd_moveRight",   nullptr, u"cmd_moveRight",   u"cmd_moveRight",    u"cmd_moveRight"},
    530    {NS_VK_LEFT,  0, MODIFIER_SHIFT,   u"cmd_selectLeft",  nullptr, u"cmd_selectLeft",  u"cmd_selectLeft",   u"cmd_selectLeft"},
    531    {NS_VK_RIGHT, 0, MODIFIER_SHIFT,   u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight",  u"cmd_selectRight"},
    532    {NS_VK_LEFT,  0, MODIFIER_CONTROL, u"cmd_moveLeft2",   nullptr, nullptr,            u"cmd_wordPrevious", u"cmd_wordPrevious"},
    533    {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2",  nullptr, nullptr,            u"cmd_wordNext",     u"cmd_wordNext"},
    534    {NS_VK_LEFT,  0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_beginLine",    nullptr},
    535    {NS_VK_RIGHT, 0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_endLine",      nullptr},
    536    {NS_VK_UP,    0, MODIFIER_NONE,    u"cmd_moveUp",      nullptr, u"cmd_moveUp",      u"cmd_moveUp",       u"cmd_moveUp"},
    537    {NS_VK_DOWN,  0, MODIFIER_NONE,    u"cmd_moveDown",    nullptr, u"cmd_moveDown",    u"cmd_moveDown",     u"cmd_moveDown"},
    538    {NS_VK_UP,    0, MODIFIER_SHIFT,   u"cmd_selectUp",    nullptr, u"cmd_selectUp",    u"cmd_selectUp",     u"cmd_selectUp"},
    539    {NS_VK_DOWN,  0, MODIFIER_SHIFT,   u"cmd_selectDown",  nullptr, u"cmd_selectDown",  u"cmd_selectDown",   u"cmd_selectDown"},
    540    {NS_VK_UP,    0, MODIFIER_CONTROL, u"cmd_moveUp2",     nullptr, nullptr,            nullptr,             nullptr},
    541    {NS_VK_DOWN,  0, MODIFIER_CONTROL, u"cmd_moveDown2",   nullptr, nullptr,            nullptr,             nullptr},
    542    {NS_VK_UP,    0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_moveTop",      nullptr},
    543    {NS_VK_DOWN,  0, MODIFIER_ALT,     nullptr,            nullptr, nullptr,            u"cmd_moveBottom",   nullptr},
    544 
    545    // KeyCode       Modifiers                          Windows              macOS    Linux    Android                    Emacs
    546    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2",  nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"},
    547    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext",     u"cmd_selectWordNext"},
    548    {NS_VK_LEFT,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectBeginLine",    nullptr},
    549    {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectEndLine",      nullptr},
    550    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2",    nullptr, nullptr, nullptr,                   nullptr},
    551    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2",  nullptr, nullptr, nullptr,                   nullptr},
    552    {NS_VK_UP,    0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectTop",          nullptr},
    553    {NS_VK_DOWN,  0, MODIFIER_SHIFT | MODIFIER_ALT,     nullptr,             nullptr, nullptr, u"cmd_selectBottom",       nullptr},
    554 
    555    // KeyCode           Modifiers       Windows                macOS    Linux    Android                Emacs
    556    {NS_VK_PAGE_UP,   0, MODIFIER_NONE,  u"cmd_movePageUp",     nullptr, nullptr, u"cmd_movePageUp",     u"cmd_movePageUp"},
    557    {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE,  u"cmd_movePageDown",   nullptr, nullptr, u"cmd_movePageDown",   u"cmd_movePageDown"},
    558    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT, u"cmd_selectPageUp",   nullptr, nullptr, u"cmd_selectPageUp",   u"cmd_selectPageUp"},
    559    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr, nullptr, u"cmd_selectPageDown", u"cmd_selectPageDown"},
    560    {NS_VK_PAGE_UP,   0, MODIFIER_ALT,   nullptr,               nullptr, nullptr, u"cmd_moveTop",        nullptr},
    561    {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT,   nullptr,               nullptr, nullptr, u"cmd_moveBottom",     nullptr},
    562 
    563    // KeyCode           Modifiers                        Windows  macOS    Linux    Android              Emacs
    564    {NS_VK_PAGE_UP,   0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectTop",    nullptr},
    565    {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT,   nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr},
    566 
    567    // KeyCode       Modifiers         Windows                 macOS    Linux    Android                 Emacs
    568    {NS_VK_HOME,  0, MODIFIER_NONE,    u"cmd_beginLine",       nullptr, nullptr, u"cmd_beginLine",       u"cmd_beginLine"},
    569    {NS_VK_END,   0, MODIFIER_NONE,    u"cmd_endLine",         nullptr, nullptr, u"cmd_endLine",         u"cmd_endLine"},
    570    {NS_VK_HOME,  0, MODIFIER_SHIFT,   u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"},
    571    {NS_VK_END,   0, MODIFIER_SHIFT,   u"cmd_selectEndLine",   nullptr, nullptr, u"cmd_selectEndLine",   u"cmd_selectEndLine"},
    572    {NS_VK_HOME,  0, MODIFIER_CONTROL, u"cmd_moveTop",         nullptr, nullptr, u"cmd_moveTop",         u"cmd_moveTop"},
    573    {NS_VK_END,   0, MODIFIER_CONTROL, u"cmd_moveBottom",      nullptr, nullptr, u"cmd_moveBottom",      u"cmd_moveBottom"},
    574 
    575    // KeyCode       Modifiers                          Windows              macOS    Linux    Android              Emacs
    576    {NS_VK_HOME,  0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop",    nullptr, nullptr, u"cmd_selectTop",    u"cmd_selectTop"},
    577    {NS_VK_END,   0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, u"cmd_selectBottom", u"cmd_selectBottom"},
    578 
    579    // KeyCode         Modifiers         Windows                    macOS    Linux    Android                         Emacs
    580    {NS_VK_INSERT,  0, MODIFIER_SHIFT,   u"cmd_paste",              nullptr, nullptr, nullptr,                        u"cmd_paste"},
    581    {NS_VK_INSERT,  0, MODIFIER_CONTROL, u"cmd_copy",               nullptr, nullptr, nullptr,                        u"cmd_copy"},
    582    {NS_VK_DELETE,  0, MODIFIER_SHIFT,   u"cmd_cutOrDelete",        nullptr, nullptr, nullptr,                        u"cmd_cutOrDelete"},
    583    {NS_VK_DELETE,  0, MODIFIER_CONTROL, u"cmd_deleteWordForward",  nullptr, nullptr, u"cmd_deleteWordForward",       u"cmd_copyOrDelete"},
    584    {NS_VK_DELETE,  0, MODIFIER_ALT,     nullptr,                   nullptr, nullptr, u"cmd_deleteToEndOfLine",       nullptr},
    585    {NS_VK_BACK,    0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward",      u"cmd_deleteWordBackward"},
    586    {NS_VK_BACK,    0, MODIFIER_ALT,     u"cmd_undo",               nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr},
    587 
    588    // KeyCode      Modifiers                      Windows      macOS    Linux    Android  Emacs
    589    {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr},
    590 
    591    // charCode Modifiers,      Windows                macOS                  Linux                  Android                Emacs
    592    {0, ' ',    MODIFIER_NONE,  u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown"},
    593    {0, ' ',    MODIFIER_SHIFT, u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp",   u"cmd_scrollPageUp"},
    594    {0, 'a',    MODIFIER_ACCEL, u"cmd_selectAll",      u"cmd_selectAll",      u"cmd_selectAll",      u"cmd_selectAll",      nullptr},
    595    {0, 'a',    MODIFIER_ALT,   nullptr,               nullptr,               nullptr,               nullptr,               u"cmd_selectAll"},
    596    {0, 'c',    MODIFIER_ACCEL, u"cmd_copy",           u"cmd_copy",           u"cmd_copy",           u"cmd_copy",           u"cmd_copy"},
    597    {0, 'x',    MODIFIER_ACCEL, u"cmd_cut",            u"cmd_cut",            u"cmd_cut",            u"cmd_cut",            u"cmd_cut"},
    598    {0, 'v',    MODIFIER_ACCEL, u"cmd_paste",          u"cmd_paste",          u"cmd_paste",          u"cmd_paste",          u"cmd_paste"},
    599    {0, 'y',    MODIFIER_ACCEL, u"cmd_redo",           nullptr,               u"cmd_redo",           nullptr,               u"cmd_redo"},
    600    {0, 'z',    MODIFIER_ACCEL, u"cmd_undo",           u"cmd_undo",           u"cmd_undo",           u"cmd_undo",           u"cmd_undo"},
    601 
    602    // charCode Modifiers                        Windows                   macOS                     Linux                     Android                   Emacs
    603    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting"},
    604    {0, 'z',    MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo",              u"cmd_redo",              u"cmd_redo",              u"cmd_redo",              u"cmd_redo"},
    605 
    606    // charCode Modifiers                                       Windows  macOS                     Linux    Android  Emacs
    607    {0, 'v',    MODIFIER_SHIFT | MODIFIER_ACCEL | MODIFIER_ALT, nullptr, u"cmd_pasteNoFormatting", nullptr, nullptr, nullptr},
    608 
    609    // charCode Modifiers         Windows  macOS    Linux    Android  Emacs
    610    {0, 'a',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"},
    611    {0, 'b',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"},
    612    {0, 'd',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"},
    613    {0, 'e',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"},
    614    {0, 'f',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"},
    615    {0, 'h',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"},
    616    {0, 'k',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"},
    617    {0, 'n',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_lineNext"},
    618    {0, 'p',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_linePrevious"},
    619    {0, 'u',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"},
    620    {0, 'w',    MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"},
    621  };
    622  // clang-format on
    623 
    624  TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eEditor), expectedMap);
    625 
    626  ShortcutKeys::Shutdown();  // Destroy the singleton instance.
    627 }
    628 
    629 #undef MODIFIER_ACCEL
    630 #undef GetCommandForPlatform
    631 
    632 }  // namespace mozilla