Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/BasicEvents.h"
7 #include "mozilla/ContentEvents.h"
8 #include "mozilla/InternalMutationEvent.h"
9 #include "mozilla/MiscEvents.h"
10 #include "mozilla/MouseEvents.h"
11 #include "mozilla/TextEvents.h"
12 #include "mozilla/TouchEvents.h"
14 namespace mozilla {
16 /******************************************************************************
17 * As*Event() implementation
18 ******************************************************************************/
20 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
21 #define NS_EVENT_CLASS(aPrefix, aName) \
22 aPrefix##aName* \
23 WidgetEvent::As##aName() \
24 { \
25 return nullptr; \
26 } \
27 \
28 const aPrefix##aName* \
29 WidgetEvent::As##aName() const \
30 { \
31 return const_cast<WidgetEvent*>(this)->As##aName(); \
32 }
34 #include "mozilla/EventClassList.h"
36 #undef NS_EVENT_CLASS
37 #undef NS_ROOT_EVENT_CLASS
39 /******************************************************************************
40 * mozilla::WidgetEvent
41 *
42 * Event struct type checking methods.
43 ******************************************************************************/
45 bool
46 WidgetEvent::IsQueryContentEvent() const
47 {
48 return eventStructType == NS_QUERY_CONTENT_EVENT;
49 }
51 bool
52 WidgetEvent::IsSelectionEvent() const
53 {
54 return eventStructType == NS_SELECTION_EVENT;
55 }
57 bool
58 WidgetEvent::IsContentCommandEvent() const
59 {
60 return eventStructType == NS_CONTENT_COMMAND_EVENT;
61 }
63 bool
64 WidgetEvent::IsNativeEventDelivererForPlugin() const
65 {
66 return eventStructType == NS_PLUGIN_EVENT;
67 }
70 /******************************************************************************
71 * mozilla::WidgetEvent
72 *
73 * Event message checking methods.
74 ******************************************************************************/
76 bool
77 WidgetEvent::HasMouseEventMessage() const
78 {
79 switch (message) {
80 case NS_MOUSE_BUTTON_DOWN:
81 case NS_MOUSE_BUTTON_UP:
82 case NS_MOUSE_CLICK:
83 case NS_MOUSE_DOUBLECLICK:
84 case NS_MOUSE_ENTER:
85 case NS_MOUSE_EXIT:
86 case NS_MOUSE_ACTIVATE:
87 case NS_MOUSE_ENTER_SYNTH:
88 case NS_MOUSE_EXIT_SYNTH:
89 case NS_MOUSE_MOZHITTEST:
90 case NS_MOUSE_MOVE:
91 return true;
92 default:
93 return false;
94 }
95 }
97 bool
98 WidgetEvent::HasDragEventMessage() const
99 {
100 switch (message) {
101 case NS_DRAGDROP_ENTER:
102 case NS_DRAGDROP_OVER:
103 case NS_DRAGDROP_EXIT:
104 case NS_DRAGDROP_DRAGDROP:
105 case NS_DRAGDROP_GESTURE:
106 case NS_DRAGDROP_DRAG:
107 case NS_DRAGDROP_END:
108 case NS_DRAGDROP_START:
109 case NS_DRAGDROP_DROP:
110 case NS_DRAGDROP_LEAVE_SYNTH:
111 return true;
112 default:
113 return false;
114 }
115 }
117 bool
118 WidgetEvent::HasKeyEventMessage() const
119 {
120 switch (message) {
121 case NS_KEY_DOWN:
122 case NS_KEY_PRESS:
123 case NS_KEY_UP:
124 return true;
125 default:
126 return false;
127 }
128 }
130 bool
131 WidgetEvent::HasIMEEventMessage() const
132 {
133 switch (message) {
134 case NS_TEXT_TEXT:
135 case NS_COMPOSITION_START:
136 case NS_COMPOSITION_END:
137 case NS_COMPOSITION_UPDATE:
138 return true;
139 default:
140 return false;
141 }
142 }
144 bool
145 WidgetEvent::HasPluginActivationEventMessage() const
146 {
147 return message == NS_PLUGIN_ACTIVATE ||
148 message == NS_PLUGIN_FOCUS;
149 }
151 /******************************************************************************
152 * mozilla::WidgetEvent
153 *
154 * Specific event checking methods.
155 ******************************************************************************/
157 bool
158 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
159 {
160 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
161 return pluginEvent && pluginEvent->retargetToFocusedDocument;
162 }
164 bool
165 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
166 {
167 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
168 return pluginEvent && !pluginEvent->retargetToFocusedDocument;
169 }
171 bool
172 WidgetEvent::IsIMERelatedEvent() const
173 {
174 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
175 }
177 bool
178 WidgetEvent::IsUsingCoordinates() const
179 {
180 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
181 if (mouseEvent) {
182 return !mouseEvent->IsContextMenuKeyEvent();
183 }
184 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
185 !HasPluginActivationEventMessage() &&
186 !IsNativeEventDelivererForPlugin() &&
187 !IsContentCommandEvent() &&
188 message != NS_PLUGIN_RESOLUTION_CHANGED;
189 }
191 bool
192 WidgetEvent::IsTargetedAtFocusedWindow() const
193 {
194 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
195 if (mouseEvent) {
196 return mouseEvent->IsContextMenuKeyEvent();
197 }
198 return HasKeyEventMessage() || IsIMERelatedEvent() ||
199 IsContentCommandEvent() ||
200 IsRetargetedNativeEventDelivererForPlugin();
201 }
203 bool
204 WidgetEvent::IsTargetedAtFocusedContent() const
205 {
206 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
207 if (mouseEvent) {
208 return mouseEvent->IsContextMenuKeyEvent();
209 }
210 return HasKeyEventMessage() || IsIMERelatedEvent() ||
211 IsRetargetedNativeEventDelivererForPlugin();
212 }
214 bool
215 WidgetEvent::IsAllowedToDispatchDOMEvent() const
216 {
217 switch (eventStructType) {
218 case NS_MOUSE_EVENT:
219 case NS_POINTER_EVENT:
220 // We want synthesized mouse moves to cause mouseover and mouseout
221 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
222 // DOM events.
223 // Synthesized button up events also do not cause DOM events because they
224 // do not have a reliable refPoint.
225 return AsMouseEvent()->reason == WidgetMouseEvent::eReal;
227 case NS_WHEEL_EVENT: {
228 // wheel event whose all delta values are zero by user pref applied, it
229 // shouldn't cause a DOM event.
230 const WidgetWheelEvent* wheelEvent = AsWheelEvent();
231 return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 ||
232 wheelEvent->deltaZ != 0.0;
233 }
235 // Following events are handled in EventStateManager, so, we don't need to
236 // dispatch DOM event for them into the DOM tree.
237 case NS_QUERY_CONTENT_EVENT:
238 case NS_SELECTION_EVENT:
239 case NS_CONTENT_COMMAND_EVENT:
240 return false;
242 default:
243 return true;
244 }
245 }
247 /******************************************************************************
248 * mozilla::WidgetKeyboardEvent (TextEvents.h)
249 ******************************************************************************/
251 /*static*/ void
252 WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
253 nsAString& aKeyName)
254 {
255 // The expected way to implement this function would be to use a
256 // switch statement. By using a table-based implementation, below, we
257 // ensure that this function executes in constant time in cases where
258 // compilers wouldn't be able to convert the switch statement to a
259 // jump table. This table-based implementation also minimizes the
260 // space required by the code and data.
261 #define KEY_STR_NUM_INTERNAL(line) key##line
262 #define KEY_STR_NUM(line) KEY_STR_NUM_INTERNAL(line)
264 // Catch non-ASCII DOM key names in our key name list.
265 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
266 static_assert(sizeof(aDOMKeyName) == MOZ_ARRAY_LENGTH(aDOMKeyName), \
267 "Invalid DOM key name");
268 #include "mozilla/KeyNameList.h"
269 #undef NS_DEFINE_KEYNAME
271 struct KeyNameTable
272 {
273 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
274 char16_t KEY_STR_NUM(__LINE__)[sizeof(aDOMKeyName)];
275 #include "mozilla/KeyNameList.h"
276 #undef NS_DEFINE_KEYNAME
277 };
279 static const KeyNameTable kKeyNameTable = {
280 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName),
281 #include "mozilla/KeyNameList.h"
282 #undef NS_DEFINE_KEYNAME
283 };
285 static const uint16_t kKeyNameOffsets[] = {
286 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
287 offsetof(struct KeyNameTable, KEY_STR_NUM(__LINE__)) / sizeof(char16_t),
288 #include "mozilla/KeyNameList.h"
289 #undef NS_DEFINE_KEYNAME
290 // Include this entry so we can compute lengths easily.
291 sizeof(kKeyNameTable)
292 };
294 // Use the sizeof trick rather than MOZ_ARRAY_LENGTH to avoid problems
295 // with constexpr functions called inside static_assert with some
296 // compilers.
297 static_assert(KEY_NAME_INDEX_USE_STRING ==
298 (sizeof(kKeyNameOffsets)/sizeof(kKeyNameOffsets[0])) - 1,
299 "Invalid enumeration values!");
301 if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
302 aKeyName.Truncate();
303 return;
304 }
306 uint16_t offset = kKeyNameOffsets[aKeyNameIndex];
307 uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1];
308 const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable);
310 // Subtract off 1 for the null terminator.
311 aKeyName.Assign(table + offset, nextOffset - offset - 1);
313 #undef KEY_STR_NUM
314 #undef KEY_STR_NUM_INTERNAL
315 }
317 /* static */ const char*
318 WidgetKeyboardEvent::GetCommandStr(Command aCommand)
319 {
320 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
321 static const char* kCommands[] = {
322 "" // CommandDoNothing
323 #include "mozilla/CommandList.h"
324 };
325 #undef NS_DEFINE_COMMAND
327 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
328 "Illegal command enumeration value");
329 return kCommands[aCommand];
330 }
332 } // namespace mozilla