|
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/. */ |
|
5 |
|
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" |
|
13 |
|
14 namespace mozilla { |
|
15 |
|
16 /****************************************************************************** |
|
17 * As*Event() implementation |
|
18 ******************************************************************************/ |
|
19 |
|
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 } |
|
33 |
|
34 #include "mozilla/EventClassList.h" |
|
35 |
|
36 #undef NS_EVENT_CLASS |
|
37 #undef NS_ROOT_EVENT_CLASS |
|
38 |
|
39 /****************************************************************************** |
|
40 * mozilla::WidgetEvent |
|
41 * |
|
42 * Event struct type checking methods. |
|
43 ******************************************************************************/ |
|
44 |
|
45 bool |
|
46 WidgetEvent::IsQueryContentEvent() const |
|
47 { |
|
48 return eventStructType == NS_QUERY_CONTENT_EVENT; |
|
49 } |
|
50 |
|
51 bool |
|
52 WidgetEvent::IsSelectionEvent() const |
|
53 { |
|
54 return eventStructType == NS_SELECTION_EVENT; |
|
55 } |
|
56 |
|
57 bool |
|
58 WidgetEvent::IsContentCommandEvent() const |
|
59 { |
|
60 return eventStructType == NS_CONTENT_COMMAND_EVENT; |
|
61 } |
|
62 |
|
63 bool |
|
64 WidgetEvent::IsNativeEventDelivererForPlugin() const |
|
65 { |
|
66 return eventStructType == NS_PLUGIN_EVENT; |
|
67 } |
|
68 |
|
69 |
|
70 /****************************************************************************** |
|
71 * mozilla::WidgetEvent |
|
72 * |
|
73 * Event message checking methods. |
|
74 ******************************************************************************/ |
|
75 |
|
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 } |
|
96 |
|
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 } |
|
116 |
|
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 } |
|
129 |
|
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 } |
|
143 |
|
144 bool |
|
145 WidgetEvent::HasPluginActivationEventMessage() const |
|
146 { |
|
147 return message == NS_PLUGIN_ACTIVATE || |
|
148 message == NS_PLUGIN_FOCUS; |
|
149 } |
|
150 |
|
151 /****************************************************************************** |
|
152 * mozilla::WidgetEvent |
|
153 * |
|
154 * Specific event checking methods. |
|
155 ******************************************************************************/ |
|
156 |
|
157 bool |
|
158 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const |
|
159 { |
|
160 const WidgetPluginEvent* pluginEvent = AsPluginEvent(); |
|
161 return pluginEvent && pluginEvent->retargetToFocusedDocument; |
|
162 } |
|
163 |
|
164 bool |
|
165 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const |
|
166 { |
|
167 const WidgetPluginEvent* pluginEvent = AsPluginEvent(); |
|
168 return pluginEvent && !pluginEvent->retargetToFocusedDocument; |
|
169 } |
|
170 |
|
171 bool |
|
172 WidgetEvent::IsIMERelatedEvent() const |
|
173 { |
|
174 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent(); |
|
175 } |
|
176 |
|
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 } |
|
190 |
|
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 } |
|
202 |
|
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 } |
|
213 |
|
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; |
|
226 |
|
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 } |
|
234 |
|
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; |
|
241 |
|
242 default: |
|
243 return true; |
|
244 } |
|
245 } |
|
246 |
|
247 /****************************************************************************** |
|
248 * mozilla::WidgetKeyboardEvent (TextEvents.h) |
|
249 ******************************************************************************/ |
|
250 |
|
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) |
|
263 |
|
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 |
|
270 |
|
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 }; |
|
278 |
|
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 }; |
|
284 |
|
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 }; |
|
293 |
|
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!"); |
|
300 |
|
301 if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) { |
|
302 aKeyName.Truncate(); |
|
303 return; |
|
304 } |
|
305 |
|
306 uint16_t offset = kKeyNameOffsets[aKeyNameIndex]; |
|
307 uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1]; |
|
308 const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable); |
|
309 |
|
310 // Subtract off 1 for the null terminator. |
|
311 aKeyName.Assign(table + offset, nextOffset - offset - 1); |
|
312 |
|
313 #undef KEY_STR_NUM |
|
314 #undef KEY_STR_NUM_INTERNAL |
|
315 } |
|
316 |
|
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 |
|
326 |
|
327 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands), |
|
328 "Illegal command enumeration value"); |
|
329 return kCommands[aCommand]; |
|
330 } |
|
331 |
|
332 } // namespace mozilla |