Bug 1885602 - Part 5: Implement navigating to the SUMO help topic from the menu heade...
[gecko.git] / dom / events / GlobalKeyListener.h
blobd3048e60a8e10f5dfa23a04d94779d7b36277153
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/. */
7 #ifndef mozilla_GlobalKeyListener_h_
8 #define mozilla_GlobalKeyListener_h_
10 #include "mozilla/EventForwards.h"
11 #include "mozilla/layers/KeyboardMap.h"
12 #include "nsIDOMEventListener.h"
13 #include "nsIWeakReferenceUtils.h"
15 class nsAtom;
17 namespace mozilla {
18 class EventListenerManager;
19 class WidgetKeyboardEvent;
20 struct IgnoreModifierState;
22 namespace layers {
23 class KeyboardMap;
26 namespace dom {
27 class Element;
28 class EventTarget;
29 class KeyboardEvent;
30 } // namespace dom
32 class KeyEventHandler;
34 /**
35 * A generic listener for key events.
37 * Maintains a list of shortcut handlers and is registered as a listener for DOM
38 * key events from a target. Responsible for executing the appropriate handler
39 * when a keyboard event is received.
41 class GlobalKeyListener : public nsIDOMEventListener {
42 public:
43 explicit GlobalKeyListener(dom::EventTarget* aTarget);
45 void InstallKeyboardEventListenersTo(
46 EventListenerManager* aEventListenerManager);
47 void RemoveKeyboardEventListenersFrom(
48 EventListenerManager* aEventListenerManager);
50 NS_DECL_ISUPPORTS
51 NS_DECL_NSIDOMEVENTLISTENER
53 protected:
54 virtual ~GlobalKeyListener() = default;
56 MOZ_CAN_RUN_SCRIPT
57 void WalkHandlers(dom::KeyboardEvent* aKeyEvent);
59 enum class Purpose {
60 ExecuteCommand,
61 LookForCommand,
63 struct MOZ_STACK_CLASS WalkHandlersResult {
64 // Set to true if it found a command matches with given keyboard event and
65 // it's available.
66 bool mMeaningfulHandlerFound = false;
67 // Set to true if the command which is found or executed is reserved for
68 // chrome.
69 bool mReservedHandlerForChromeFound = false;
70 // Set to true if found handler is disabled.
71 bool mDisabledHandlerFound = false;
74 // walk the handlers, looking for one to handle the event
75 MOZ_CAN_RUN_SCRIPT
76 WalkHandlersResult WalkHandlersInternal(Purpose aPurpose,
77 dom::KeyboardEvent* aKeyEvent);
79 // Walk the handlers for aEvent, aCharCode and aIgnoreModifierState.
80 MOZ_CAN_RUN_SCRIPT
81 WalkHandlersResult WalkHandlersAndExecute(
82 Purpose aPurpose, dom::KeyboardEvent* aKeyEvent, uint32_t aCharCode,
83 const IgnoreModifierState& aIgnoreModifierState);
85 // HandleEvent function for the capturing phase in the default event group.
86 MOZ_CAN_RUN_SCRIPT
87 void HandleEventOnCaptureInDefaultEventGroup(dom::KeyboardEvent* aEvent);
88 // HandleEvent function for the capturing phase in the system event group.
89 MOZ_CAN_RUN_SCRIPT
90 void HandleEventOnCaptureInSystemEventGroup(dom::KeyboardEvent* aEvent);
92 // Check if any handler would handle the given event. Optionally returns
93 // whether the command handler for the event is marked with the "reserved"
94 // attribute.
95 MOZ_CAN_RUN_SCRIPT
96 WalkHandlersResult HasHandlerForEvent(dom::KeyboardEvent* aEvent);
98 // Returns true if the key would be reserved for the given handler. A reserved
99 // key is not sent to a content process or single-process equivalent.
100 bool IsReservedKey(WidgetKeyboardEvent* aKeyEvent, KeyEventHandler* aHandler);
102 // lazily load the handlers. Overridden to handle being attached
103 // to a particular element rather than the document
104 virtual void EnsureHandlers() = 0;
106 virtual bool CanHandle(KeyEventHandler* aHandler, bool aWillExecute) const {
107 return true;
110 virtual bool IsDisabled() const { return false; }
112 virtual already_AddRefed<dom::EventTarget> GetHandlerTarget(
113 KeyEventHandler* aHandler) {
114 return do_AddRef(mTarget);
117 dom::EventTarget* mTarget; // weak ref;
119 KeyEventHandler* mHandler; // Linked list of event handlers.
123 * A listener for shortcut keys defined in XUL keyset elements.
125 * Listens for keyboard events from the document object and triggers the
126 * appropriate XUL key elements.
128 class XULKeySetGlobalKeyListener final : public GlobalKeyListener {
129 public:
130 explicit XULKeySetGlobalKeyListener(dom::Element* aElement,
131 dom::EventTarget* aTarget);
133 static void AttachKeyHandler(dom::Element* aElementTarget);
134 static void DetachKeyHandler(dom::Element* aElementTarget);
136 protected:
137 virtual ~XULKeySetGlobalKeyListener();
139 // Returns the element which was passed as a parameter to the constructor,
140 // unless the element has been removed from the document. Optionally returns
141 // whether the disabled attribute is set on the element (assuming the element
142 // is non-null).
143 dom::Element* GetElement(bool* aIsDisabled = nullptr) const;
145 virtual void EnsureHandlers() override;
147 virtual bool CanHandle(KeyEventHandler* aHandler,
148 bool aWillExecute) const override;
149 virtual bool IsDisabled() const override;
150 virtual already_AddRefed<dom::EventTarget> GetHandlerTarget(
151 KeyEventHandler* aHandler) override;
154 * GetElementForHandler() retrieves an element for the handler. The element
155 * may be a command element or a key element.
157 * @param aHandler The handler.
158 * @param aElementForHandler Must not be nullptr. The element is returned to
159 * this.
160 * @return true if the handler is valid. Otherwise, false.
162 bool GetElementForHandler(KeyEventHandler* aHandler,
163 dom::Element** aElementForHandler) const;
166 * IsExecutableElement() returns true if aElement is executable.
167 * Otherwise, false. aElement should be a command element or a key element.
169 bool IsExecutableElement(dom::Element* aElement) const;
171 // Using weak pointer to the DOM Element.
172 nsWeakPtr mWeakPtrForElement;
176 * Listens for built-in shortcut keys.
178 * Listens to DOM keyboard events from the window or text input and runs the
179 * built-in shortcuts (see dom/events/keyevents) as necessary.
181 class RootWindowGlobalKeyListener final : public GlobalKeyListener {
182 public:
183 explicit RootWindowGlobalKeyListener(dom::EventTarget* aTarget);
185 static void AttachKeyHandler(dom::EventTarget* aTarget);
187 static layers::KeyboardMap CollectKeyboardShortcuts();
189 protected:
190 // Is an HTML editable element focused
191 static bool IsHTMLEditorFocused();
193 virtual void EnsureHandlers() override;
196 } // namespace mozilla
198 #endif