tor-browser

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

ShortcutKeys.cpp (3403B)


      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 "ShortcutKeys.h"
      8 
      9 #include "mozilla/KeyEventHandler.h"
     10 #include "mozilla/TextEvents.h"
     11 #include "nsAtom.h"
     12 #include "nsContentUtils.h"
     13 
     14 namespace mozilla {
     15 
     16 NS_IMPL_ISUPPORTS(ShortcutKeys, nsIObserver);
     17 
     18 StaticRefPtr<ShortcutKeys> ShortcutKeys::sInstance;
     19 
     20 ShortcutKeys::ShortcutKeys()
     21    : mBrowserHandlers(nullptr),
     22      mEditorHandlers(nullptr),
     23      mInputHandlers(nullptr),
     24      mTextAreaHandlers(nullptr) {
     25  MOZ_ASSERT(!sInstance, "Attempt to instantiate a second ShortcutKeys.");
     26  nsContentUtils::RegisterShutdownObserver(this);
     27 }
     28 
     29 ShortcutKeys::~ShortcutKeys() {
     30  delete mBrowserHandlers;
     31  delete mEditorHandlers;
     32  delete mInputHandlers;
     33  delete mTextAreaHandlers;
     34 }
     35 
     36 nsresult ShortcutKeys::Observe(nsISupports* aSubject, const char* aTopic,
     37                               const char16_t* aData) {
     38  // Clear our strong reference so we can clean up.
     39  ShortcutKeys::Shutdown();
     40  return NS_OK;
     41 }
     42 
     43 void ShortcutKeys::Shutdown() { sInstance = nullptr; }
     44 
     45 /* static */
     46 KeyEventHandler* ShortcutKeys::GetHandlers(HandlerType aType) {
     47  if (!sInstance) {
     48    sInstance = new ShortcutKeys();
     49  }
     50 
     51  return sInstance->EnsureHandlers(aType);
     52 }
     53 
     54 /* static */
     55 nsAtom* ShortcutKeys::ConvertEventToDOMEventType(
     56    const WidgetKeyboardEvent* aWidgetKeyboardEvent) {
     57  switch (aWidgetKeyboardEvent->mMessage) {
     58    case eKeyDown:
     59      return nsGkAtoms::keydown;
     60    case eKeyUp:
     61      return nsGkAtoms::keyup;
     62    // eAccessKeyNotFound event is always created from eKeyPress event and
     63    // the original eKeyPress event has stopped its propagation before
     64    // dispatched into the DOM tree in this process and not matched with remote
     65    // content's access keys.  So, we should treat it as an eKeyPress event and
     66    // execute a command if it's registered as a shortcut key.
     67    case eKeyPress:
     68    case eAccessKeyNotFound:
     69      return nsGkAtoms::keypress;
     70    default:
     71      MOZ_ASSERT_UNREACHABLE(
     72          "All event messages relating to shortcut keys should be handled");
     73      return nullptr;
     74  }
     75 }
     76 
     77 KeyEventHandler* ShortcutKeys::EnsureHandlers(HandlerType aType) {
     78  ShortcutKeyData* keyData;
     79  KeyEventHandler** cache;
     80 
     81  switch (aType) {
     82    case HandlerType::eBrowser:
     83      keyData = &sBrowserHandlers[0];
     84      cache = &mBrowserHandlers;
     85      break;
     86    case HandlerType::eEditor:
     87      keyData = &sEditorHandlers[0];
     88      cache = &mEditorHandlers;
     89      break;
     90    case HandlerType::eInput:
     91      keyData = &sInputHandlers[0];
     92      cache = &mInputHandlers;
     93      break;
     94    case HandlerType::eTextArea:
     95      keyData = &sTextAreaHandlers[0];
     96      cache = &mTextAreaHandlers;
     97      break;
     98    default:
     99      MOZ_ASSERT(false, "Unknown handler type requested.");
    100  }
    101 
    102  if (*cache) {
    103    return *cache;
    104  }
    105 
    106  KeyEventHandler* lastHandler = nullptr;
    107  while (keyData->event) {
    108    KeyEventHandler* handler = new KeyEventHandler(keyData);
    109    if (lastHandler) {
    110      lastHandler->SetNextHandler(handler);
    111    } else {
    112      *cache = handler;
    113    }
    114    lastHandler = handler;
    115    keyData++;
    116  }
    117 
    118  return *cache;
    119 }
    120 
    121 }  // namespace mozilla