DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (fc9d28ae4655)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_KeyEventHandler_h_
#define mozilla_KeyEventHandler_h_

#include "mozilla/EventForwards.h"
#include "mozilla/MemoryReporting.h"
#include "nsAtom.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIController.h"
#include "nsAutoPtr.h"
#include "nsIWeakReference.h"
#include "nsCycleCollectionParticipant.h"
#include "js/TypeDecls.h"
#include "mozilla/ShortcutKeys.h"

namespace mozilla {

namespace layers {
class KeyboardShortcut;
}  // namespace layers

struct IgnoreModifierState;

namespace dom {
class Event;
class UIEvent;
class Element;
class EventTarget;
class KeyboardEvent;
class Element;
}  // namespace dom

using namespace dom;

// Values of the reserved attribute. When unset, the default value depends on
// the permissions.default.shortcuts preference.
enum ReservedKey : uint8_t {
  ReservedKey_False = 0,
  ReservedKey_True = 1,
  ReservedKey_Unset = 2,
};

class KeyEventHandler final {
 public:
  // This constructor is used only by XUL key handlers (e.g., <key>)
  explicit KeyEventHandler(Element* aHandlerElement, ReservedKey aReserved);

  // This constructor is used for keyboard handlers for browser, editor, input
  // and textarea elements.
  explicit KeyEventHandler(ShortcutKeyData* aKeyData);

  ~KeyEventHandler();

  /**
   * Try and convert this XBL handler into an APZ KeyboardShortcut for handling
   * key events on the compositor thread. This only works for XBL handlers that
   * represent scroll commands.
   *
   * @param aOut the converted KeyboardShortcut, must be non null
   * @return whether the handler was converted into a KeyboardShortcut
   */
  bool TryConvertToKeyboardShortcut(layers::KeyboardShortcut* aOut) const;

  bool EventTypeEquals(nsAtom* aEventType) const {
    return mEventName == aEventType;
  }

  // if aCharCode is not zero, it is used instead of the charCode of
  // aKeyEventHandler.
  bool KeyEventMatched(KeyboardEvent* aDomKeyboardEvent, uint32_t aCharCode,
                       const IgnoreModifierState& aIgnoreModifierState);

  already_AddRefed<Element> GetHandlerElement();

  ReservedKey GetIsReserved() { return mReserved; }

  KeyEventHandler* GetNextHandler() { return mNextHandler; }
  void SetNextHandler(KeyEventHandler* aHandler) { mNextHandler = aHandler; }

  MOZ_CAN_RUN_SCRIPT
  nsresult ExecuteHandler(EventTarget* aTarget, Event* aEvent);

  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;

 public:
  static uint32_t gRefCnt;

 protected:
  void Init() {
    ++gRefCnt;
    if (gRefCnt == 1) {
      // Get the primary accelerator key.
      InitAccessKeys();
    }
  }

  already_AddRefed<nsIController> GetController(EventTarget* aTarget);

  inline int32_t GetMatchingKeyCode(const nsAString& aKeyName);
  void ConstructPrototype(Element* aKeyElement,
                          const char16_t* aEvent = nullptr,
                          const char16_t* aCommand = nullptr,
                          const char16_t* aKeyCode = nullptr,
                          const char16_t* aCharCode = nullptr,
                          const char16_t* aModifiers = nullptr);
  void BuildModifiers(nsAString& aModifiers);

  void ReportKeyConflict(const char16_t* aKey, const char16_t* aModifiers,
                         Element* aKeyElement, const char* aMessageName);
  void GetEventType(nsAString& aEvent);
  bool ModifiersMatchMask(UIEvent* aEvent,
                          const IgnoreModifierState& aIgnoreModifierState);
  MOZ_CAN_RUN_SCRIPT
  nsresult DispatchXBLCommand(EventTarget* aTarget, Event* aEvent);
  MOZ_CAN_RUN_SCRIPT
  nsresult DispatchXULKeyCommand(Event* aEvent);

  Modifiers GetModifiers() const;
  Modifiers GetModifiersMask() const;

  static int32_t KeyToMask(int32_t key);
  static int32_t AccelKeyMask();

  static int32_t kMenuAccessKey;
  static void InitAccessKeys();

  static const int32_t cShift;
  static const int32_t cAlt;
  static const int32_t cControl;
  static const int32_t cMeta;
  static const int32_t cOS;

  static const int32_t cShiftMask;
  static const int32_t cAltMask;
  static const int32_t cControlMask;
  static const int32_t cMetaMask;
  static const int32_t cOSMask;

  static const int32_t cAllModifiers;

 protected:
  union {
    nsIWeakReference*
        mHandlerElement;  // For XUL <key> element handlers. [STRONG]
    char16_t* mCommand;   // For built-in shortcuts the command to execute.
  };

  // The following four values make up 32 bits.
  bool mIsXULKey;  // This handler is either for a XUL <key> element or it is
                   // a command dispatcher.
  uint8_t mMisc;   // Miscellaneous extra information.  For key events,
                   // stores whether or not we're a key code or char code.
                   // For mouse events, stores the clickCount.

  ReservedKey mReserved;  // <key> is reserved for chrome. Not used by handlers.

  int32_t mKeyMask;  // Which modifier keys this event handler expects to have
                     // down in order to be matched.

  // The primary filter information for mouse/key events.
  int32_t mDetail;  // For key events, contains a charcode or keycode. For
                    // mouse events, stores the button info.

  // Prototype handlers are chained. We own the next handler in the chain.
  KeyEventHandler* mNextHandler;
  RefPtr<nsAtom> mEventName;  // The type of the event, e.g., "keypress"
};

}  // namespace mozilla

#endif