/work/obj-fuzz/dist/include/mozilla/BasicEvents.h
Line | Count | Source (jump to first uncovered line) |
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 | | #ifndef mozilla_BasicEvents_h__ |
7 | | #define mozilla_BasicEvents_h__ |
8 | | |
9 | | #include <stdint.h> |
10 | | |
11 | | #include "mozilla/dom/EventTarget.h" |
12 | | #include "mozilla/EventForwards.h" |
13 | | #include "mozilla/TimeStamp.h" |
14 | | #include "nsCOMPtr.h" |
15 | | #include "nsAtom.h" |
16 | | #include "nsISupportsImpl.h" |
17 | | #include "nsIWidget.h" |
18 | | #include "nsString.h" |
19 | | #include "Units.h" |
20 | | |
21 | | #ifdef DEBUG |
22 | | #include "nsXULAppAPI.h" |
23 | | #endif // #ifdef DEBUG |
24 | | |
25 | | namespace IPC { |
26 | | template<typename T> |
27 | | struct ParamTraits; |
28 | | } // namespace IPC |
29 | | |
30 | | namespace mozilla { |
31 | | |
32 | | class EventTargetChainItem; |
33 | | |
34 | | enum class CrossProcessForwarding |
35 | | { |
36 | | // eStop prevents the event to be sent to remote process. |
37 | | eStop, |
38 | | // eAllow keeps current state of the event whether it's sent to remote |
39 | | // process. In other words, eAllow does NOT mean that making the event |
40 | | // sent to remote process when IsCrossProcessForwardingStopped() returns |
41 | | // true. |
42 | | eAllow, |
43 | | }; |
44 | | |
45 | | /****************************************************************************** |
46 | | * mozilla::BaseEventFlags |
47 | | * |
48 | | * BaseEventFlags must be a POD struct for safe to use memcpy (including |
49 | | * in ParamTraits<BaseEventFlags>). So don't make virtual methods, constructor, |
50 | | * destructor and operators. |
51 | | * This is necessary for VC which is NOT C++0x compiler. |
52 | | ******************************************************************************/ |
53 | | |
54 | | struct BaseEventFlags |
55 | | { |
56 | | public: |
57 | | // If mIsTrusted is true, the event is a trusted event. Otherwise, it's |
58 | | // an untrusted event. |
59 | | bool mIsTrusted : 1; |
60 | | // If mInBubblingPhase is true, the event is in bubbling phase or target |
61 | | // phase. |
62 | | bool mInBubblingPhase : 1; |
63 | | // If mInCapturePhase is true, the event is in capture phase or target phase. |
64 | | bool mInCapturePhase : 1; |
65 | | // If mInSystemGroup is true, the event is being dispatched in system group. |
66 | | bool mInSystemGroup: 1; |
67 | | // If mCancelable is true, the event can be consumed. I.e., calling |
68 | | // dom::Event::PreventDefault() can prevent the default action. |
69 | | bool mCancelable : 1; |
70 | | // If mBubbles is true, the event can bubble. Otherwise, cannot be handled |
71 | | // in bubbling phase. |
72 | | bool mBubbles : 1; |
73 | | // If mPropagationStopped is true, dom::Event::StopPropagation() or |
74 | | // dom::Event::StopImmediatePropagation() has been called. |
75 | | bool mPropagationStopped : 1; |
76 | | // If mImmediatePropagationStopped is true, |
77 | | // dom::Event::StopImmediatePropagation() has been called. |
78 | | // Note that mPropagationStopped must be true when this is true. |
79 | | bool mImmediatePropagationStopped : 1; |
80 | | // If mDefaultPrevented is true, the event has been consumed. |
81 | | // E.g., dom::Event::PreventDefault() has been called or |
82 | | // the default action has been performed. |
83 | | bool mDefaultPrevented : 1; |
84 | | // If mDefaultPreventedByContent is true, the event has been |
85 | | // consumed by content. |
86 | | // Note that mDefaultPrevented must be true when this is true. |
87 | | bool mDefaultPreventedByContent : 1; |
88 | | // If mDefaultPreventedByChrome is true, the event has been |
89 | | // consumed by chrome. |
90 | | // Note that mDefaultPrevented must be true when this is true. |
91 | | bool mDefaultPreventedByChrome : 1; |
92 | | // mMultipleActionsPrevented may be used when default handling don't want to |
93 | | // be prevented, but only one of the event targets should handle the event. |
94 | | // For example, when a <label> element is in another <label> element and |
95 | | // the first <label> element is clicked, that one may set this true. |
96 | | // Then, the second <label> element won't handle the event. |
97 | | bool mMultipleActionsPrevented : 1; |
98 | | // If mIsBeingDispatched is true, the DOM event created from the event is |
99 | | // dispatching into the DOM tree and not completed. |
100 | | bool mIsBeingDispatched : 1; |
101 | | // If mDispatchedAtLeastOnce is true, the event has been dispatched |
102 | | // as a DOM event and the dispatch has been completed. |
103 | | bool mDispatchedAtLeastOnce : 1; |
104 | | // If mIsSynthesizedForTests is true, the event has been synthesized for |
105 | | // automated tests or something hacky approach of an add-on. |
106 | | bool mIsSynthesizedForTests : 1; |
107 | | // If mExceptionWasRaised is true, one of the event handlers has raised an |
108 | | // exception. |
109 | | bool mExceptionWasRaised : 1; |
110 | | // If mRetargetToNonNativeAnonymous is true and the target is in a non-native |
111 | | // native anonymous subtree, the event target is set to mOriginalTarget. |
112 | | bool mRetargetToNonNativeAnonymous : 1; |
113 | | // If mNoContentDispatch is true, the event is never dispatched to the |
114 | | // event handlers which are added to the contents, onfoo attributes and |
115 | | // properties. Note that this flag is ignored when |
116 | | // EventChainPreVisitor::mForceContentDispatch is set true. For exapmle, |
117 | | // window and document object sets it true. Therefore, web applications |
118 | | // can handle the event if they add event listeners to the window or the |
119 | | // document. |
120 | | // XXX This is an ancient and broken feature, don't use this for new bug |
121 | | // as far as possible. |
122 | | bool mNoContentDispatch : 1; |
123 | | // If mOnlyChromeDispatch is true, the event is dispatched to only chrome. |
124 | | bool mOnlyChromeDispatch : 1; |
125 | | // Indicates if the key combination is reserved by chrome. This is set by |
126 | | // MarkAsReservedByChrome(). |
127 | | bool mIsReservedByChrome : 1; |
128 | | // If mOnlySystemGroupDispatchInContent is true, event listeners added to |
129 | | // the default group for non-chrome EventTarget won't be called. |
130 | | // Be aware, if this is true, EventDispatcher needs to check if each event |
131 | | // listener is added to chrome node, so, don't set this to true for the |
132 | | // events which are fired a lot of times like eMouseMove. |
133 | | bool mOnlySystemGroupDispatchInContent : 1; |
134 | | // The event's action will be handled by APZ. The main thread should not |
135 | | // perform its associated action. This is currently only relevant for |
136 | | // wheel and touch events. |
137 | | bool mHandledByAPZ : 1; |
138 | | // True if the event is currently being handled by an event listener that |
139 | | // was registered as a passive listener. |
140 | | bool mInPassiveListener: 1; |
141 | | // If mComposed is true, the event fired by nodes in shadow DOM can cross the |
142 | | // boundary of shadow DOM and light DOM. |
143 | | bool mComposed : 1; |
144 | | // Similar to mComposed. Set it to true to allow events cross the boundary |
145 | | // between native non-anonymous content and native anonymouse content |
146 | | bool mComposedInNativeAnonymousContent : 1; |
147 | | // Set to true for events which are suppressed or delayed so that later a |
148 | | // DelayedEvent of it is dispatched. This is used when parent side process |
149 | | // the key event after content side, and may drop the event if the event |
150 | | // was suppressed or delayed in contents side. |
151 | | // It is also set to true for the events (in a DelayedInputEvent), which will |
152 | | // be dispatched afterwards. |
153 | | bool mIsSuppressedOrDelayed : 1; |
154 | | // Certain mouse events can be marked as positionless to return 0 from |
155 | | // coordinate related getters. |
156 | | bool mIsPositionless : 1; |
157 | | |
158 | | // Flags managing state of propagation between processes. |
159 | | // Note the the following flags shouldn't be referred directly. Use utility |
160 | | // methods instead. |
161 | | |
162 | | // If mNoRemoteProcessDispatch is true, the event is not allowed to be sent |
163 | | // to remote process. |
164 | | bool mNoRemoteProcessDispatch : 1; |
165 | | // If mWantReplyFromContentProcess is true, the event will be redispatched |
166 | | // in the parent process after the content process has handled it. Useful |
167 | | // for when the parent process need the know first how the event was used |
168 | | // by content before handling it itself. |
169 | | bool mWantReplyFromContentProcess : 1; |
170 | | // If mPostedToRemoteProcess is true, the event has been posted to the |
171 | | // remote process (but it's not handled yet if it's not a duplicated event |
172 | | // instance). |
173 | | bool mPostedToRemoteProcess : 1; |
174 | | |
175 | | // If the event is being handled in target phase, returns true. |
176 | | inline bool InTargetPhase() const |
177 | 0 | { |
178 | 0 | return (mInBubblingPhase && mInCapturePhase); |
179 | 0 | } |
180 | | |
181 | | /** |
182 | | * Helper methods for methods of DOM Event. |
183 | | */ |
184 | | inline void StopPropagation() |
185 | 0 | { |
186 | 0 | mPropagationStopped = true; |
187 | 0 | } |
188 | | inline void StopImmediatePropagation() |
189 | 0 | { |
190 | 0 | StopPropagation(); |
191 | 0 | mImmediatePropagationStopped = true; |
192 | 0 | } |
193 | | inline void PreventDefault(bool aCalledByDefaultHandler = true) |
194 | 0 | { |
195 | 0 | if (!mCancelable) { |
196 | 0 | return; |
197 | 0 | } |
198 | 0 | mDefaultPrevented = true; |
199 | 0 | // Note that even if preventDefault() has already been called by chrome, |
200 | 0 | // a call of preventDefault() by content needs to overwrite |
201 | 0 | // mDefaultPreventedByContent to true because in such case, defaultPrevented |
202 | 0 | // must be true when web apps check it after they call preventDefault(). |
203 | 0 | if (aCalledByDefaultHandler) { |
204 | 0 | StopCrossProcessForwarding(); |
205 | 0 | mDefaultPreventedByChrome = true; |
206 | 0 | } else { |
207 | 0 | mDefaultPreventedByContent = true; |
208 | 0 | } |
209 | 0 | } |
210 | | // This should be used only before dispatching events into the DOM tree. |
211 | | inline void |
212 | | PreventDefaultBeforeDispatch(CrossProcessForwarding aCrossProcessForwarding) |
213 | 0 | { |
214 | 0 | if (!mCancelable) { |
215 | 0 | return; |
216 | 0 | } |
217 | 0 | mDefaultPrevented = true; |
218 | 0 | if (aCrossProcessForwarding == CrossProcessForwarding::eStop) { |
219 | 0 | StopCrossProcessForwarding(); |
220 | 0 | } |
221 | 0 | } |
222 | | inline bool DefaultPrevented() const |
223 | 0 | { |
224 | 0 | return mDefaultPrevented; |
225 | 0 | } |
226 | | inline bool DefaultPreventedByContent() const |
227 | 0 | { |
228 | 0 | MOZ_ASSERT(!mDefaultPreventedByContent || DefaultPrevented()); |
229 | 0 | return mDefaultPreventedByContent; |
230 | 0 | } |
231 | | inline bool IsTrusted() const |
232 | 0 | { |
233 | 0 | return mIsTrusted; |
234 | 0 | } |
235 | | inline bool PropagationStopped() const |
236 | 0 | { |
237 | 0 | return mPropagationStopped; |
238 | 0 | } |
239 | | |
240 | | // Helper methods to access flags managing state of propagation between |
241 | | // processes. |
242 | | |
243 | | /** |
244 | | * Prevent to be dispatched to remote process. |
245 | | */ |
246 | | inline void StopCrossProcessForwarding() |
247 | 0 | { |
248 | 0 | MOZ_ASSERT(!mPostedToRemoteProcess); |
249 | 0 | mNoRemoteProcessDispatch = true; |
250 | 0 | mWantReplyFromContentProcess = false; |
251 | 0 | } |
252 | | /** |
253 | | * Return true if the event shouldn't be dispatched to remote process. |
254 | | */ |
255 | | inline bool IsCrossProcessForwardingStopped() const |
256 | 0 | { |
257 | 0 | return mNoRemoteProcessDispatch; |
258 | 0 | } |
259 | | /** |
260 | | * Mark the event as waiting reply from remote process. |
261 | | * If the caller needs to win other keyboard event handlers in chrome, |
262 | | * the caller should call StopPropagation() too. |
263 | | * Otherwise, if the caller just needs to know if the event is consumed by |
264 | | * either content or chrome, it should just call this because the event |
265 | | * may be reserved by chrome and it needs to be dispatched into the DOM |
266 | | * tree in chrome for checking if it's reserved before being sent to any |
267 | | * remote processes. |
268 | | */ |
269 | | inline void MarkAsWaitingReplyFromRemoteProcess() |
270 | 0 | { |
271 | 0 | MOZ_ASSERT(!mPostedToRemoteProcess); |
272 | 0 | mNoRemoteProcessDispatch = false; |
273 | 0 | mWantReplyFromContentProcess = true; |
274 | 0 | } |
275 | | /** |
276 | | * Reset "waiting reply from remote process" state. This is useful when |
277 | | * you dispatch a copy of an event coming from different process. |
278 | | */ |
279 | | inline void ResetWaitingReplyFromRemoteProcessState() |
280 | 0 | { |
281 | 0 | if (IsWaitingReplyFromRemoteProcess()) { |
282 | 0 | // FYI: mWantReplyFromContentProcess is also used for indicating |
283 | 0 | // "handled in remote process" state. Therefore, only when |
284 | 0 | // IsWaitingReplyFromRemoteProcess() returns true, this should |
285 | 0 | // reset the flag. |
286 | 0 | mWantReplyFromContentProcess = false; |
287 | 0 | } |
288 | 0 | } |
289 | | /** |
290 | | * Return true if the event handler should wait reply event. I.e., if this |
291 | | * returns true, any event handler should do nothing with the event. |
292 | | */ |
293 | | inline bool IsWaitingReplyFromRemoteProcess() const |
294 | 0 | { |
295 | 0 | return !mNoRemoteProcessDispatch && mWantReplyFromContentProcess; |
296 | 0 | } |
297 | | /** |
298 | | * Mark the event as already handled in the remote process. This should be |
299 | | * called when initializing reply events. |
300 | | */ |
301 | | inline void MarkAsHandledInRemoteProcess() |
302 | 0 | { |
303 | 0 | mNoRemoteProcessDispatch = true; |
304 | 0 | mWantReplyFromContentProcess = true; |
305 | 0 | mPostedToRemoteProcess = false; |
306 | 0 | } |
307 | | /** |
308 | | * Return true if the event has already been handled in the remote process. |
309 | | */ |
310 | | inline bool IsHandledInRemoteProcess() const |
311 | 0 | { |
312 | 0 | return mNoRemoteProcessDispatch && mWantReplyFromContentProcess; |
313 | 0 | } |
314 | | /** |
315 | | * Return true if the event should be sent back to its parent process. |
316 | | */ |
317 | | inline bool WantReplyFromContentProcess() const |
318 | 0 | { |
319 | 0 | MOZ_ASSERT(!XRE_IsParentProcess()); |
320 | 0 | return IsWaitingReplyFromRemoteProcess(); |
321 | 0 | } |
322 | | /** |
323 | | * Mark the event has already posted to a remote process. |
324 | | */ |
325 | | inline void MarkAsPostedToRemoteProcess() |
326 | 0 | { |
327 | 0 | MOZ_ASSERT(!IsCrossProcessForwardingStopped()); |
328 | 0 | mPostedToRemoteProcess = true; |
329 | 0 | } |
330 | | /** |
331 | | * Reset the cross process dispatching state. This should be used when a |
332 | | * process receives the event because the state is in the sender. |
333 | | */ |
334 | | inline void ResetCrossProcessDispatchingState() |
335 | 0 | { |
336 | 0 | MOZ_ASSERT(!IsCrossProcessForwardingStopped()); |
337 | 0 | mPostedToRemoteProcess = false; |
338 | 0 | // Ignore propagation state in the different process if it's marked as |
339 | 0 | // "waiting reply from remote process" because the process needs to |
340 | 0 | // stop propagation in the process until receiving a reply event. |
341 | 0 | if (IsWaitingReplyFromRemoteProcess()) { |
342 | 0 | mPropagationStopped = mImmediatePropagationStopped = false; |
343 | 0 | } |
344 | 0 | } |
345 | | /** |
346 | | * Return true if the event has been posted to a remote process. |
347 | | * Note that MarkAsPostedToRemoteProcess() is called by |
348 | | * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible |
349 | | * that posting the event failed even if this returns true. But that must |
350 | | * really rare. If that'd be problem for you, you should unmark this in |
351 | | * TabParent or somewhere. |
352 | | */ |
353 | | inline bool HasBeenPostedToRemoteProcess() const |
354 | 0 | { |
355 | 0 | return mPostedToRemoteProcess; |
356 | 0 | } |
357 | | /** |
358 | | * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to |
359 | | * content because it shouldn't be cancelable. |
360 | | */ |
361 | | inline void MarkAsReservedByChrome() |
362 | 0 | { |
363 | 0 | MOZ_ASSERT(!mPostedToRemoteProcess); |
364 | 0 | mIsReservedByChrome = true; |
365 | 0 | // For reserved commands (such as Open New Tab), we don't need to wait for |
366 | 0 | // the content to answer, neither to give a chance for content to override |
367 | 0 | // its behavior. |
368 | 0 | StopCrossProcessForwarding(); |
369 | 0 | // If the event is reserved by chrome, we shouldn't expose the event to |
370 | 0 | // web contents because such events shouldn't be cancelable. So, it's not |
371 | 0 | // good behavior to fire such events but to ignore the defaultPrevented |
372 | 0 | // attribute value in chrome. |
373 | 0 | mOnlySystemGroupDispatchInContent = true; |
374 | 0 | } |
375 | | /** |
376 | | * Return true if the event is reserved by chrome. |
377 | | */ |
378 | | inline bool IsReservedByChrome() const |
379 | 0 | { |
380 | 0 | MOZ_ASSERT(!mIsReservedByChrome || |
381 | 0 | (IsCrossProcessForwardingStopped() && |
382 | 0 | mOnlySystemGroupDispatchInContent)); |
383 | 0 | return mIsReservedByChrome; |
384 | 0 | } |
385 | | |
386 | | inline void Clear() |
387 | 0 | { |
388 | 0 | SetRawFlags(0); |
389 | 0 | } |
390 | | // Get if either the instance's bit or the aOther's bit is true, the |
391 | | // instance's bit becomes true. In other words, this works like: |
392 | | // eventFlags |= aOther; |
393 | | inline void Union(const BaseEventFlags& aOther) |
394 | 0 | { |
395 | 0 | RawFlags rawFlags = GetRawFlags() | aOther.GetRawFlags(); |
396 | 0 | SetRawFlags(rawFlags); |
397 | 0 | } |
398 | | |
399 | | private: |
400 | | typedef uint32_t RawFlags; |
401 | | |
402 | | inline void SetRawFlags(RawFlags aRawFlags) |
403 | 0 | { |
404 | 0 | static_assert(sizeof(BaseEventFlags) <= sizeof(RawFlags), |
405 | 0 | "mozilla::EventFlags must not be bigger than the RawFlags"); |
406 | 0 | memcpy(this, &aRawFlags, sizeof(BaseEventFlags)); |
407 | 0 | } |
408 | | inline RawFlags GetRawFlags() const |
409 | 0 | { |
410 | 0 | RawFlags result = 0; |
411 | 0 | memcpy(&result, this, sizeof(BaseEventFlags)); |
412 | 0 | return result; |
413 | 0 | } |
414 | | }; |
415 | | |
416 | | /****************************************************************************** |
417 | | * mozilla::EventFlags |
418 | | ******************************************************************************/ |
419 | | |
420 | | struct EventFlags : public BaseEventFlags |
421 | | { |
422 | | EventFlags() |
423 | 0 | { |
424 | 0 | Clear(); |
425 | 0 | } |
426 | | }; |
427 | | |
428 | | /****************************************************************************** |
429 | | * mozilla::WidgetEventTime |
430 | | ******************************************************************************/ |
431 | | |
432 | | class WidgetEventTime |
433 | | { |
434 | | public: |
435 | | // Elapsed time, in milliseconds, from a platform-specific zero time |
436 | | // to the time the message was created |
437 | | uint64_t mTime; |
438 | | // Timestamp when the message was created. Set in parallel to 'time' until we |
439 | | // determine if it is safe to drop 'time' (see bug 77992). |
440 | | TimeStamp mTimeStamp; |
441 | | |
442 | | WidgetEventTime() |
443 | | : mTime(0) |
444 | | , mTimeStamp(TimeStamp::Now()) |
445 | 0 | { |
446 | 0 | } |
447 | | |
448 | | WidgetEventTime(uint64_t aTime, |
449 | | TimeStamp aTimeStamp) |
450 | | : mTime(aTime) |
451 | | , mTimeStamp(aTimeStamp) |
452 | 0 | { |
453 | 0 | } |
454 | | |
455 | | void AssignEventTime(const WidgetEventTime& aOther) |
456 | 0 | { |
457 | 0 | mTime = aOther.mTime; |
458 | 0 | mTimeStamp = aOther.mTimeStamp; |
459 | 0 | } |
460 | | }; |
461 | | |
462 | | /****************************************************************************** |
463 | | * mozilla::WidgetEvent |
464 | | ******************************************************************************/ |
465 | | |
466 | | class WidgetEvent : public WidgetEventTime |
467 | | { |
468 | | private: |
469 | | void SetDefaultCancelableAndBubbles() |
470 | 0 | { |
471 | 0 | switch (mClass) { |
472 | 0 | case eEditorInputEventClass: |
473 | 0 | mFlags.mCancelable = false; |
474 | 0 | mFlags.mBubbles = mFlags.mIsTrusted; |
475 | 0 | break; |
476 | 0 | case eMouseEventClass: |
477 | 0 | mFlags.mCancelable = (mMessage != eMouseEnter && |
478 | 0 | mMessage != eMouseLeave); |
479 | 0 | mFlags.mBubbles = (mMessage != eMouseEnter && |
480 | 0 | mMessage != eMouseLeave); |
481 | 0 | break; |
482 | 0 | case ePointerEventClass: |
483 | 0 | mFlags.mCancelable = (mMessage != ePointerEnter && |
484 | 0 | mMessage != ePointerLeave && |
485 | 0 | mMessage != ePointerCancel && |
486 | 0 | mMessage != ePointerGotCapture && |
487 | 0 | mMessage != ePointerLostCapture); |
488 | 0 | mFlags.mBubbles = (mMessage != ePointerEnter && |
489 | 0 | mMessage != ePointerLeave); |
490 | 0 | break; |
491 | 0 | case eDragEventClass: |
492 | 0 | mFlags.mCancelable = (mMessage != eDragExit && |
493 | 0 | mMessage != eDragLeave && |
494 | 0 | mMessage != eDragEnd); |
495 | 0 | mFlags.mBubbles = true; |
496 | 0 | break; |
497 | 0 | case eSMILTimeEventClass: |
498 | 0 | mFlags.mCancelable = false; |
499 | 0 | mFlags.mBubbles = false; |
500 | 0 | break; |
501 | 0 | case eTransitionEventClass: |
502 | 0 | case eAnimationEventClass: |
503 | 0 | mFlags.mCancelable = false; |
504 | 0 | mFlags.mBubbles = true; |
505 | 0 | break; |
506 | 0 | case eCompositionEventClass: |
507 | 0 | // XXX compositionstart is cancelable in draft of DOM3 Events. |
508 | 0 | // However, it doesn't make sense for us, we cannot cancel |
509 | 0 | // composition when we send compositionstart event. |
510 | 0 | mFlags.mCancelable = false; |
511 | 0 | mFlags.mBubbles = true; |
512 | 0 | break; |
513 | 0 | default: |
514 | 0 | if (mMessage == eResize) { |
515 | 0 | mFlags.mCancelable = false; |
516 | 0 | } else { |
517 | 0 | mFlags.mCancelable = true; |
518 | 0 | } |
519 | 0 | mFlags.mBubbles = true; |
520 | 0 | break; |
521 | 0 | } |
522 | 0 | } |
523 | | |
524 | | protected: |
525 | | WidgetEvent(bool aIsTrusted, |
526 | | EventMessage aMessage, |
527 | | EventClassID aEventClassID) |
528 | | : WidgetEventTime() |
529 | | , mClass(aEventClassID) |
530 | | , mMessage(aMessage) |
531 | | , mRefPoint(0, 0) |
532 | | , mLastRefPoint(0, 0) |
533 | | , mFocusSequenceNumber(0) |
534 | | , mSpecifiedEventType(nullptr) |
535 | | , mPath(nullptr) |
536 | 0 | { |
537 | 0 | MOZ_COUNT_CTOR(WidgetEvent); |
538 | 0 | mFlags.Clear(); |
539 | 0 | mFlags.mIsTrusted = aIsTrusted; |
540 | 0 | SetDefaultCancelableAndBubbles(); |
541 | 0 | SetDefaultComposed(); |
542 | 0 | SetDefaultComposedInNativeAnonymousContent(); |
543 | 0 | } |
544 | | |
545 | | WidgetEvent() |
546 | | : WidgetEventTime() |
547 | | , mPath(nullptr) |
548 | 0 | { |
549 | 0 | MOZ_COUNT_CTOR(WidgetEvent); |
550 | 0 | } |
551 | | |
552 | | public: |
553 | | WidgetEvent(bool aIsTrusted, EventMessage aMessage) |
554 | | : WidgetEvent(aIsTrusted, aMessage, eBasicEventClass) |
555 | 0 | { |
556 | 0 | } |
557 | | |
558 | | virtual ~WidgetEvent() |
559 | 0 | { |
560 | 0 | MOZ_COUNT_DTOR(WidgetEvent); |
561 | 0 | } |
562 | | |
563 | | WidgetEvent(const WidgetEvent& aOther) |
564 | | : WidgetEventTime() |
565 | 0 | { |
566 | 0 | MOZ_COUNT_CTOR(WidgetEvent); |
567 | 0 | *this = aOther; |
568 | 0 | } |
569 | 0 | WidgetEvent& operator=(const WidgetEvent& aOther) = default; |
570 | | |
571 | | WidgetEvent(WidgetEvent&& aOther) |
572 | | : WidgetEventTime(std::move(aOther)) |
573 | | , mClass(aOther.mClass) |
574 | | , mMessage(aOther.mMessage) |
575 | | , mRefPoint(std::move(aOther.mRefPoint)) |
576 | | , mLastRefPoint(std::move(aOther.mLastRefPoint)) |
577 | | , mFocusSequenceNumber(aOther.mFocusSequenceNumber) |
578 | | , mFlags(std::move(aOther.mFlags)) |
579 | | , mSpecifiedEventType(std::move(aOther.mSpecifiedEventType)) |
580 | | , mSpecifiedEventTypeString(std::move(aOther.mSpecifiedEventTypeString)) |
581 | | , mTarget(std::move(aOther.mTarget)) |
582 | | , mCurrentTarget(std::move(aOther.mCurrentTarget)) |
583 | | , mOriginalTarget(std::move(aOther.mOriginalTarget)) |
584 | | , mRelatedTarget(std::move(aOther.mRelatedTarget)) |
585 | | , mOriginalRelatedTarget(std::move(aOther.mOriginalRelatedTarget)) |
586 | | , mPath(std::move(aOther.mPath)) |
587 | 0 | { |
588 | 0 | MOZ_COUNT_CTOR(WidgetEvent); |
589 | 0 | } |
590 | | WidgetEvent& operator=(WidgetEvent&& aOther) = default; |
591 | | |
592 | | virtual WidgetEvent* Duplicate() const |
593 | 0 | { |
594 | 0 | MOZ_ASSERT(mClass == eBasicEventClass, |
595 | 0 | "Duplicate() must be overridden by sub class"); |
596 | 0 | WidgetEvent* result = new WidgetEvent(false, mMessage); |
597 | 0 | result->AssignEventData(*this, true); |
598 | 0 | result->mFlags = mFlags; |
599 | 0 | return result; |
600 | 0 | } |
601 | | |
602 | | EventClassID mClass; |
603 | | EventMessage mMessage; |
604 | | // Relative to the widget of the event, or if there is no widget then it is |
605 | | // in screen coordinates. Not modified by layout code. |
606 | | LayoutDeviceIntPoint mRefPoint; |
607 | | // The previous mRefPoint, if known, used to calculate mouse movement deltas. |
608 | | LayoutDeviceIntPoint mLastRefPoint; |
609 | | // The sequence number of the last potentially focus changing event handled |
610 | | // by APZ. This is used to track when that event has been processed by content, |
611 | | // and focus can be reconfirmed for async keyboard scrolling. |
612 | | uint64_t mFocusSequenceNumber; |
613 | | // See BaseEventFlags definition for the detail. |
614 | | BaseEventFlags mFlags; |
615 | | |
616 | | // If JS creates an event with unknown event type or known event type but |
617 | | // for different event interface, the event type is stored to this. |
618 | | // NOTE: This is always used if the instance is a WidgetCommandEvent instance. |
619 | | RefPtr<nsAtom> mSpecifiedEventType; |
620 | | |
621 | | // nsAtom isn't available on non-main thread due to unsafe. Therefore, |
622 | | // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if |
623 | | // the event is created in non-main thread. |
624 | | nsString mSpecifiedEventTypeString; |
625 | | |
626 | | // Event targets, needed by DOM Events |
627 | | // Note that when you need event target for DOM event, you should use |
628 | | // Get*DOMEventTarget() instead of accessing these members directly. |
629 | | nsCOMPtr<dom::EventTarget> mTarget; |
630 | | nsCOMPtr<dom::EventTarget> mCurrentTarget; |
631 | | nsCOMPtr<dom::EventTarget> mOriginalTarget; |
632 | | |
633 | | /// The possible related target |
634 | | nsCOMPtr<dom::EventTarget> mRelatedTarget; |
635 | | nsCOMPtr<dom::EventTarget> mOriginalRelatedTarget; |
636 | | |
637 | | nsTArray<EventTargetChainItem>* mPath; |
638 | | |
639 | | dom::EventTarget* GetDOMEventTarget() const; |
640 | | dom::EventTarget* GetCurrentDOMEventTarget() const; |
641 | | dom::EventTarget* GetOriginalDOMEventTarget() const; |
642 | | |
643 | | void AssignEventData(const WidgetEvent& aEvent, bool aCopyTargets) |
644 | 0 | { |
645 | 0 | // mClass should be initialized with the constructor. |
646 | 0 | // mMessage should be initialized with the constructor. |
647 | 0 | mRefPoint = aEvent.mRefPoint; |
648 | 0 | // mLastRefPoint doesn't need to be copied. |
649 | 0 | mFocusSequenceNumber = aEvent.mFocusSequenceNumber; |
650 | 0 | AssignEventTime(aEvent); |
651 | 0 | // mFlags should be copied manually if it's necessary. |
652 | 0 | mSpecifiedEventType = aEvent.mSpecifiedEventType; |
653 | 0 | // mSpecifiedEventTypeString should be copied manually if it's necessary. |
654 | 0 | mTarget = aCopyTargets ? aEvent.mTarget : nullptr; |
655 | 0 | mCurrentTarget = aCopyTargets ? aEvent.mCurrentTarget : nullptr; |
656 | 0 | mOriginalTarget = aCopyTargets ? aEvent.mOriginalTarget : nullptr; |
657 | 0 | mRelatedTarget = aCopyTargets ? aEvent.mRelatedTarget : nullptr; |
658 | 0 | mOriginalRelatedTarget = |
659 | 0 | aCopyTargets ? aEvent.mOriginalRelatedTarget : nullptr; |
660 | 0 | } |
661 | | |
662 | | /** |
663 | | * Helper methods for methods of DOM Event. |
664 | | */ |
665 | 0 | void StopPropagation() { mFlags.StopPropagation(); } |
666 | 0 | void StopImmediatePropagation() { mFlags.StopImmediatePropagation(); } |
667 | | void PreventDefault(bool aCalledByDefaultHandler = true, |
668 | | nsIPrincipal* aPrincipal = nullptr); |
669 | | |
670 | | void |
671 | | PreventDefaultBeforeDispatch(CrossProcessForwarding aCrossProcessForwarding) |
672 | 0 | { |
673 | 0 | mFlags.PreventDefaultBeforeDispatch(aCrossProcessForwarding); |
674 | 0 | } |
675 | 0 | bool DefaultPrevented() const { return mFlags.DefaultPrevented(); } |
676 | | bool DefaultPreventedByContent() const |
677 | 0 | { |
678 | 0 | return mFlags.DefaultPreventedByContent(); |
679 | 0 | } |
680 | 0 | bool IsTrusted() const { return mFlags.IsTrusted(); } |
681 | 0 | bool PropagationStopped() const { return mFlags.PropagationStopped(); } |
682 | | |
683 | | /** |
684 | | * Prevent to be dispatched to remote process. |
685 | | */ |
686 | | inline void StopCrossProcessForwarding() |
687 | 0 | { |
688 | 0 | mFlags.StopCrossProcessForwarding(); |
689 | 0 | } |
690 | | /** |
691 | | * Return true if the event shouldn't be dispatched to remote process. |
692 | | */ |
693 | | inline bool IsCrossProcessForwardingStopped() const |
694 | 0 | { |
695 | 0 | return mFlags.IsCrossProcessForwardingStopped(); |
696 | 0 | } |
697 | | /** |
698 | | * Mark the event as waiting reply from remote process. |
699 | | * Note that this also stops immediate propagation in current process. |
700 | | */ |
701 | | inline void MarkAsWaitingReplyFromRemoteProcess() |
702 | 0 | { |
703 | 0 | mFlags.MarkAsWaitingReplyFromRemoteProcess(); |
704 | 0 | } |
705 | | /** |
706 | | * Reset "waiting reply from remote process" state. This is useful when |
707 | | * you dispatch a copy of an event coming from different process. |
708 | | */ |
709 | | inline void ResetWaitingReplyFromRemoteProcessState() |
710 | 0 | { |
711 | 0 | mFlags.ResetWaitingReplyFromRemoteProcessState(); |
712 | 0 | } |
713 | | /** |
714 | | * Return true if the event handler should wait reply event. I.e., if this |
715 | | * returns true, any event handler should do nothing with the event. |
716 | | */ |
717 | | inline bool IsWaitingReplyFromRemoteProcess() const |
718 | 0 | { |
719 | 0 | return mFlags.IsWaitingReplyFromRemoteProcess(); |
720 | 0 | } |
721 | | /** |
722 | | * Mark the event as already handled in the remote process. This should be |
723 | | * called when initializing reply events. |
724 | | */ |
725 | | inline void MarkAsHandledInRemoteProcess() |
726 | 0 | { |
727 | 0 | mFlags.MarkAsHandledInRemoteProcess(); |
728 | 0 | } |
729 | | /** |
730 | | * Return true if the event has already been handled in the remote process. |
731 | | * I.e., if this returns true, the event is a reply event. |
732 | | */ |
733 | | inline bool IsHandledInRemoteProcess() const |
734 | 0 | { |
735 | 0 | return mFlags.IsHandledInRemoteProcess(); |
736 | 0 | } |
737 | | /** |
738 | | * Return true if the event should be sent back to its parent process. |
739 | | * So, usual event handlers shouldn't call this. |
740 | | */ |
741 | | inline bool WantReplyFromContentProcess() const |
742 | 0 | { |
743 | 0 | return mFlags.WantReplyFromContentProcess(); |
744 | 0 | } |
745 | | /** |
746 | | * Mark the event has already posted to a remote process. |
747 | | */ |
748 | | inline void MarkAsPostedToRemoteProcess() |
749 | 0 | { |
750 | 0 | mFlags.MarkAsPostedToRemoteProcess(); |
751 | 0 | } |
752 | | /** |
753 | | * Reset the cross process dispatching state. This should be used when a |
754 | | * process receives the event because the state is in the sender. |
755 | | */ |
756 | | inline void ResetCrossProcessDispatchingState() |
757 | 0 | { |
758 | 0 | mFlags.ResetCrossProcessDispatchingState(); |
759 | 0 | } |
760 | | /** |
761 | | * Return true if the event has been posted to a remote process. |
762 | | */ |
763 | | inline bool HasBeenPostedToRemoteProcess() const |
764 | 0 | { |
765 | 0 | return mFlags.HasBeenPostedToRemoteProcess(); |
766 | 0 | } |
767 | | /** |
768 | | * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to |
769 | | * content because it shouldn't be cancelable. |
770 | | */ |
771 | | inline void MarkAsReservedByChrome() |
772 | 0 | { |
773 | 0 | mFlags.MarkAsReservedByChrome(); |
774 | 0 | } |
775 | | /** |
776 | | * Return true if the event is reserved by chrome. |
777 | | */ |
778 | | inline bool IsReservedByChrome() const |
779 | 0 | { |
780 | 0 | return mFlags.IsReservedByChrome(); |
781 | 0 | } |
782 | | |
783 | | /** |
784 | | * Utils for checking event types |
785 | | */ |
786 | | |
787 | | /** |
788 | | * As*Event() returns the pointer of the instance only when the instance is |
789 | | * the class or one of its derived class. |
790 | | */ |
791 | | #define NS_ROOT_EVENT_CLASS(aPrefix, aName) |
792 | | #define NS_EVENT_CLASS(aPrefix, aName) \ |
793 | | virtual aPrefix##aName* As##aName(); \ |
794 | | const aPrefix##aName* As##aName() const; |
795 | | |
796 | | #include "mozilla/EventClassList.h" |
797 | | |
798 | | #undef NS_EVENT_CLASS |
799 | | #undef NS_ROOT_EVENT_CLASS |
800 | | |
801 | | /** |
802 | | * Returns true if the event is a query content event. |
803 | | */ |
804 | | bool IsQueryContentEvent() const; |
805 | | /** |
806 | | * Returns true if the event is a selection event. |
807 | | */ |
808 | | bool IsSelectionEvent() const; |
809 | | /** |
810 | | * Returns true if the event is a content command event. |
811 | | */ |
812 | | bool IsContentCommandEvent() const; |
813 | | /** |
814 | | * Returns true if the event is a native event deliverer event for plugin. |
815 | | */ |
816 | | bool IsNativeEventDelivererForPlugin() const; |
817 | | |
818 | | /** |
819 | | * Returns true if the event mMessage is one of mouse events. |
820 | | */ |
821 | | bool HasMouseEventMessage() const; |
822 | | /** |
823 | | * Returns true if the event mMessage is one of drag events. |
824 | | */ |
825 | | bool HasDragEventMessage() const; |
826 | | /** |
827 | | * Returns true if aMessage or mMessage is one of key events. |
828 | | */ |
829 | | static bool IsKeyEventMessage(EventMessage aMessage); |
830 | | bool HasKeyEventMessage() const |
831 | 0 | { |
832 | 0 | return IsKeyEventMessage(mMessage); |
833 | 0 | } |
834 | | /** |
835 | | * Returns true if the event mMessage is one of composition events or text |
836 | | * event. |
837 | | */ |
838 | | bool HasIMEEventMessage() const; |
839 | | /** |
840 | | * Returns true if the event mMessage is one of plugin activation events. |
841 | | */ |
842 | | bool HasPluginActivationEventMessage() const; |
843 | | |
844 | | /** |
845 | | * Returns true if the event can be sent to remote process. |
846 | | */ |
847 | | bool CanBeSentToRemoteProcess() const; |
848 | | /** |
849 | | * Returns true if the original target is a remote process and the event |
850 | | * will be posted to the remote process later. |
851 | | */ |
852 | | bool WillBeSentToRemoteProcess() const; |
853 | | /** |
854 | | * Returns true if the event is native event deliverer event for plugin and |
855 | | * it should be retarted to focused document. |
856 | | */ |
857 | | bool IsRetargetedNativeEventDelivererForPlugin() const; |
858 | | /** |
859 | | * Returns true if the event is native event deliverer event for plugin and |
860 | | * it should NOT be retarted to focused document. |
861 | | */ |
862 | | bool IsNonRetargetedNativeEventDelivererForPlugin() const; |
863 | | /** |
864 | | * Returns true if the event is related to IME handling. It includes |
865 | | * IME events, query content events and selection events. |
866 | | * Be careful when you use this. |
867 | | */ |
868 | | bool IsIMERelatedEvent() const; |
869 | | |
870 | | /** |
871 | | * Whether the event should be handled by the frame of the mouse cursor |
872 | | * position or not. When it should be handled there (e.g., the mouse events), |
873 | | * this returns true. |
874 | | */ |
875 | | bool IsUsingCoordinates() const; |
876 | | /** |
877 | | * Whether the event should be handled by the focused DOM window in the |
878 | | * same top level window's or not. E.g., key events, IME related events |
879 | | * (including the query content events, they are used in IME transaction) |
880 | | * should be handled by the (last) focused window rather than the dispatched |
881 | | * window. |
882 | | * |
883 | | * NOTE: Even if this returns true, the event isn't going to be handled by the |
884 | | * application level active DOM window which is on another top level window. |
885 | | * So, when the event is fired on a deactive window, the event is going to be |
886 | | * handled by the last focused DOM window in the last focused window. |
887 | | */ |
888 | | bool IsTargetedAtFocusedWindow() const; |
889 | | /** |
890 | | * Whether the event should be handled by the focused content or not. E.g., |
891 | | * key events, IME related events and other input events which are not handled |
892 | | * by the frame of the mouse cursor position. |
893 | | * |
894 | | * NOTE: Even if this returns true, the event isn't going to be handled by the |
895 | | * application level active DOM window which is on another top level window. |
896 | | * So, when the event is fired on a deactive window, the event is going to be |
897 | | * handled by the last focused DOM element of the last focused DOM window in |
898 | | * the last focused window. |
899 | | */ |
900 | | bool IsTargetedAtFocusedContent() const; |
901 | | /** |
902 | | * Whether the event should cause a DOM event. |
903 | | */ |
904 | | bool IsAllowedToDispatchDOMEvent() const; |
905 | | /** |
906 | | * Whether the event should be dispatched in system group. |
907 | | */ |
908 | | bool IsAllowedToDispatchInSystemGroup() const; |
909 | | /** |
910 | | * Whether the event should be blocked for fingerprinting resistance. |
911 | | */ |
912 | | bool IsBlockedForFingerprintingResistance() const; |
913 | | /** |
914 | | * Initialize mComposed |
915 | | */ |
916 | | void SetDefaultComposed() |
917 | 0 | { |
918 | 0 | switch (mClass) { |
919 | 0 | case eCompositionEventClass: |
920 | 0 | mFlags.mComposed = mMessage == eCompositionStart || |
921 | 0 | mMessage == eCompositionUpdate || |
922 | 0 | mMessage == eCompositionEnd; |
923 | 0 | break; |
924 | 0 | case eDragEventClass: |
925 | 0 | // All drag & drop events are composed |
926 | 0 | mFlags.mComposed = mMessage == eDrag || mMessage == eDragEnd || |
927 | 0 | mMessage == eDragEnter || mMessage == eDragExit || |
928 | 0 | mMessage == eDragLeave || mMessage == eDragOver || |
929 | 0 | mMessage == eDragStart || mMessage == eDrop; |
930 | 0 | break; |
931 | 0 | case eEditorInputEventClass: |
932 | 0 | mFlags.mComposed = mMessage == eEditorInput; |
933 | 0 | break; |
934 | 0 | case eFocusEventClass: |
935 | 0 | mFlags.mComposed = mMessage == eBlur || mMessage == eFocus || |
936 | 0 | mMessage == eFocusOut || mMessage == eFocusIn; |
937 | 0 | break; |
938 | 0 | case eKeyboardEventClass: |
939 | 0 | mFlags.mComposed = mMessage == eKeyDown || mMessage == eKeyUp || |
940 | 0 | mMessage == eKeyPress; |
941 | 0 | break; |
942 | 0 | case eMouseEventClass: |
943 | 0 | mFlags.mComposed = mMessage == eMouseClick || |
944 | 0 | mMessage == eMouseDoubleClick || |
945 | 0 | mMessage == eMouseAuxClick || |
946 | 0 | mMessage == eMouseDown || mMessage == eMouseUp || |
947 | 0 | mMessage == eMouseOver || mMessage == eMouseOut || |
948 | 0 | mMessage == eMouseMove || mMessage == eContextMenu; |
949 | 0 | break; |
950 | 0 | case ePointerEventClass: |
951 | 0 | // All pointer events are composed |
952 | 0 | mFlags.mComposed = mMessage == ePointerDown || |
953 | 0 | mMessage == ePointerMove || mMessage == ePointerUp || |
954 | 0 | mMessage == ePointerCancel || |
955 | 0 | mMessage == ePointerOver || |
956 | 0 | mMessage == ePointerOut || |
957 | 0 | mMessage == ePointerGotCapture || |
958 | 0 | mMessage == ePointerLostCapture; |
959 | 0 | break; |
960 | 0 | case eTouchEventClass: |
961 | 0 | // All touch events are composed |
962 | 0 | mFlags.mComposed = mMessage == eTouchStart || mMessage == eTouchEnd || |
963 | 0 | mMessage == eTouchMove || mMessage == eTouchCancel; |
964 | 0 | break; |
965 | 0 | case eUIEventClass: |
966 | 0 | mFlags.mComposed = mMessage == eLegacyDOMFocusIn || |
967 | 0 | mMessage == eLegacyDOMFocusOut || |
968 | 0 | mMessage == eLegacyDOMActivate; |
969 | 0 | break; |
970 | 0 | case eWheelEventClass: |
971 | 0 | // All wheel events are composed |
972 | 0 | mFlags.mComposed = mMessage == eWheel; |
973 | 0 | break; |
974 | 0 | default: |
975 | 0 | mFlags.mComposed = false; |
976 | 0 | break; |
977 | 0 | } |
978 | 0 | } |
979 | | |
980 | | void SetComposed(const nsAString& aEventTypeArg) |
981 | 0 | { |
982 | 0 | mFlags.mComposed = // composition events |
983 | 0 | aEventTypeArg.EqualsLiteral("compositionstart") || |
984 | 0 | aEventTypeArg.EqualsLiteral("compositionupdate") || |
985 | 0 | aEventTypeArg.EqualsLiteral("compositionend") || |
986 | 0 | // drag and drop events |
987 | 0 | aEventTypeArg.EqualsLiteral("dragstart") || |
988 | 0 | aEventTypeArg.EqualsLiteral("drag") || |
989 | 0 | aEventTypeArg.EqualsLiteral("dragenter") || |
990 | 0 | aEventTypeArg.EqualsLiteral("dragexit") || |
991 | 0 | aEventTypeArg.EqualsLiteral("dragleave") || |
992 | 0 | aEventTypeArg.EqualsLiteral("dragover") || |
993 | 0 | aEventTypeArg.EqualsLiteral("drop") || |
994 | 0 | aEventTypeArg.EqualsLiteral("dropend") || |
995 | 0 | // editor input events |
996 | 0 | aEventTypeArg.EqualsLiteral("input") || |
997 | 0 | aEventTypeArg.EqualsLiteral("beforeinput") || |
998 | 0 | // focus events |
999 | 0 | aEventTypeArg.EqualsLiteral("blur") || |
1000 | 0 | aEventTypeArg.EqualsLiteral("focus") || |
1001 | 0 | aEventTypeArg.EqualsLiteral("focusin") || |
1002 | 0 | aEventTypeArg.EqualsLiteral("focusout") || |
1003 | 0 | // keyboard events |
1004 | 0 | aEventTypeArg.EqualsLiteral("keydown") || |
1005 | 0 | aEventTypeArg.EqualsLiteral("keyup") || |
1006 | 0 | aEventTypeArg.EqualsLiteral("keypress") || |
1007 | 0 | // mouse events |
1008 | 0 | aEventTypeArg.EqualsLiteral("click") || |
1009 | 0 | aEventTypeArg.EqualsLiteral("dblclick") || |
1010 | 0 | aEventTypeArg.EqualsLiteral("mousedown") || |
1011 | 0 | aEventTypeArg.EqualsLiteral("mouseup") || |
1012 | 0 | aEventTypeArg.EqualsLiteral("mouseenter") || |
1013 | 0 | aEventTypeArg.EqualsLiteral("mouseleave") || |
1014 | 0 | aEventTypeArg.EqualsLiteral("mouseover") || |
1015 | 0 | aEventTypeArg.EqualsLiteral("mouseout") || |
1016 | 0 | aEventTypeArg.EqualsLiteral("mousemove") || |
1017 | 0 | aEventTypeArg.EqualsLiteral("contextmenu") || |
1018 | 0 | // pointer events |
1019 | 0 | aEventTypeArg.EqualsLiteral("pointerdown") || |
1020 | 0 | aEventTypeArg.EqualsLiteral("pointermove") || |
1021 | 0 | aEventTypeArg.EqualsLiteral("pointerup") || |
1022 | 0 | aEventTypeArg.EqualsLiteral("pointercancel") || |
1023 | 0 | aEventTypeArg.EqualsLiteral("pointerover") || |
1024 | 0 | aEventTypeArg.EqualsLiteral("pointerout") || |
1025 | 0 | aEventTypeArg.EqualsLiteral("pointerenter") || |
1026 | 0 | aEventTypeArg.EqualsLiteral("pointerleave") || |
1027 | 0 | aEventTypeArg.EqualsLiteral("gotpointercapture") || |
1028 | 0 | aEventTypeArg.EqualsLiteral("lostpointercapture") || |
1029 | 0 | // touch events |
1030 | 0 | aEventTypeArg.EqualsLiteral("touchstart") || |
1031 | 0 | aEventTypeArg.EqualsLiteral("touchend") || |
1032 | 0 | aEventTypeArg.EqualsLiteral("touchmove") || |
1033 | 0 | aEventTypeArg.EqualsLiteral("touchcancel") || |
1034 | 0 | // UI legacy events |
1035 | 0 | aEventTypeArg.EqualsLiteral("DOMFocusIn") || |
1036 | 0 | aEventTypeArg.EqualsLiteral("DOMFocusOut") || |
1037 | 0 | aEventTypeArg.EqualsLiteral("DOMActivate") || |
1038 | 0 | // wheel events |
1039 | 0 | aEventTypeArg.EqualsLiteral("wheel"); |
1040 | 0 | } |
1041 | | |
1042 | | void SetComposed(bool aComposed) |
1043 | 0 | { |
1044 | 0 | mFlags.mComposed = aComposed; |
1045 | 0 | } |
1046 | | |
1047 | | void SetDefaultComposedInNativeAnonymousContent() |
1048 | 0 | { |
1049 | 0 | // For compatibility concerns, we set mComposedInNativeAnonymousContent to |
1050 | 0 | // false for those events we want to stop propagation. |
1051 | 0 | // |
1052 | 0 | // nsVideoFrame may create anonymous image element which fires eLoad, |
1053 | 0 | // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross |
1054 | 0 | // the boundary of NAC |
1055 | 0 | mFlags.mComposedInNativeAnonymousContent = mMessage != eLoad && |
1056 | 0 | mMessage != eLoadStart && |
1057 | 0 | mMessage != eLoadEnd && |
1058 | 0 | mMessage != eLoadError; |
1059 | 0 | } |
1060 | | |
1061 | | bool IsUserAction() const; |
1062 | | }; |
1063 | | |
1064 | | /****************************************************************************** |
1065 | | * mozilla::NativeEventData |
1066 | | * |
1067 | | * WidgetGUIEvent's mPluginEvent member used to be a void* pointer, |
1068 | | * used to reference external, OS-specific data structures. |
1069 | | * |
1070 | | * That void* pointer wasn't serializable by itself, causing |
1071 | | * certain plugin events not to function in e10s. See bug 586656. |
1072 | | * |
1073 | | * To make this serializable, we changed this void* pointer into |
1074 | | * a proper buffer, and copy these external data structures into this |
1075 | | * buffer. |
1076 | | * |
1077 | | * That buffer is NativeEventData::mBuffer below. |
1078 | | * |
1079 | | * We wrap this in that NativeEventData class providing operators to |
1080 | | * be compatible with existing code that was written around |
1081 | | * the old void* field. |
1082 | | ******************************************************************************/ |
1083 | | |
1084 | | class NativeEventData final |
1085 | | { |
1086 | | nsTArray<uint8_t> mBuffer; |
1087 | | |
1088 | | friend struct IPC::ParamTraits<mozilla::NativeEventData>; |
1089 | | |
1090 | | public: |
1091 | | |
1092 | | explicit operator bool() const |
1093 | 0 | { |
1094 | 0 | return !mBuffer.IsEmpty(); |
1095 | 0 | } |
1096 | | |
1097 | | template<typename T> |
1098 | | explicit operator const T*() const |
1099 | 0 | { |
1100 | 0 | return mBuffer.IsEmpty() |
1101 | 0 | ? nullptr |
1102 | 0 | : reinterpret_cast<const T*>(mBuffer.Elements()); |
1103 | 0 | } |
1104 | | |
1105 | | template <typename T> |
1106 | | void Copy(const T& other) |
1107 | 0 | { |
1108 | 0 | static_assert(!mozilla::IsPointer<T>::value, "Don't want a pointer!"); |
1109 | 0 | mBuffer.SetLength(sizeof(T)); |
1110 | 0 | memcpy(mBuffer.Elements(), &other, mBuffer.Length()); |
1111 | 0 | } |
1112 | | |
1113 | | void Clear() |
1114 | 0 | { |
1115 | 0 | mBuffer.Clear(); |
1116 | 0 | } |
1117 | | }; |
1118 | | |
1119 | | /****************************************************************************** |
1120 | | * mozilla::WidgetGUIEvent |
1121 | | ******************************************************************************/ |
1122 | | |
1123 | | class WidgetGUIEvent : public WidgetEvent |
1124 | | { |
1125 | | protected: |
1126 | | WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget, |
1127 | | EventClassID aEventClassID) |
1128 | | : WidgetEvent(aIsTrusted, aMessage, aEventClassID) |
1129 | | , mWidget(aWidget) |
1130 | 0 | { |
1131 | 0 | } |
1132 | | |
1133 | | WidgetGUIEvent() |
1134 | 0 | { |
1135 | 0 | } |
1136 | | |
1137 | | public: |
1138 | 0 | virtual WidgetGUIEvent* AsGUIEvent() override { return this; } |
1139 | | |
1140 | | WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget) |
1141 | | : WidgetEvent(aIsTrusted, aMessage, eGUIEventClass) |
1142 | | , mWidget(aWidget) |
1143 | 0 | { |
1144 | 0 | } |
1145 | | |
1146 | | virtual WidgetEvent* Duplicate() const override |
1147 | 0 | { |
1148 | 0 | MOZ_ASSERT(mClass == eGUIEventClass, |
1149 | 0 | "Duplicate() must be overridden by sub class"); |
1150 | 0 | // Not copying widget, it is a weak reference. |
1151 | 0 | WidgetGUIEvent* result = new WidgetGUIEvent(false, mMessage, nullptr); |
1152 | 0 | result->AssignGUIEventData(*this, true); |
1153 | 0 | result->mFlags = mFlags; |
1154 | 0 | return result; |
1155 | 0 | } |
1156 | | |
1157 | | // Originator of the event |
1158 | | nsCOMPtr<nsIWidget> mWidget; |
1159 | | |
1160 | | /* |
1161 | | * Ideally though, we wouldn't allow arbitrary reinterpret_cast'ing here; |
1162 | | * instead, we would at least store type information here so that |
1163 | | * this class can't be used to reinterpret one structure type into another. |
1164 | | * We can also wonder if it would be possible to properly extend |
1165 | | * WidgetGUIEvent and other Event classes to remove the need for this |
1166 | | * mPluginEvent field. |
1167 | | */ |
1168 | | typedef NativeEventData PluginEvent; |
1169 | | |
1170 | | // Event for NPAPI plugin |
1171 | | PluginEvent mPluginEvent; |
1172 | | |
1173 | | void AssignGUIEventData(const WidgetGUIEvent& aEvent, bool aCopyTargets) |
1174 | 0 | { |
1175 | 0 | AssignEventData(aEvent, aCopyTargets); |
1176 | 0 |
|
1177 | 0 | // widget should be initialized with the constructor. |
1178 | 0 |
|
1179 | 0 | mPluginEvent = aEvent.mPluginEvent; |
1180 | 0 | } |
1181 | | }; |
1182 | | |
1183 | | /****************************************************************************** |
1184 | | * mozilla::Modifier |
1185 | | * |
1186 | | * All modifier keys should be defined here. This is used for managing |
1187 | | * modifier states for DOM Level 3 or later. |
1188 | | ******************************************************************************/ |
1189 | | |
1190 | | enum Modifier |
1191 | | { |
1192 | | MODIFIER_NONE = 0x0000, |
1193 | | MODIFIER_ALT = 0x0001, |
1194 | | MODIFIER_ALTGRAPH = 0x0002, |
1195 | | MODIFIER_CAPSLOCK = 0x0004, |
1196 | | MODIFIER_CONTROL = 0x0008, |
1197 | | MODIFIER_FN = 0x0010, |
1198 | | MODIFIER_FNLOCK = 0x0020, |
1199 | | MODIFIER_META = 0x0040, |
1200 | | MODIFIER_NUMLOCK = 0x0080, |
1201 | | MODIFIER_SCROLLLOCK = 0x0100, |
1202 | | MODIFIER_SHIFT = 0x0200, |
1203 | | MODIFIER_SYMBOL = 0x0400, |
1204 | | MODIFIER_SYMBOLLOCK = 0x0800, |
1205 | | MODIFIER_OS = 0x1000 |
1206 | | }; |
1207 | | |
1208 | | /****************************************************************************** |
1209 | | * Modifier key names. |
1210 | | ******************************************************************************/ |
1211 | | |
1212 | | #define NS_DOM_KEYNAME_ALT "Alt" |
1213 | | #define NS_DOM_KEYNAME_ALTGRAPH "AltGraph" |
1214 | | #define NS_DOM_KEYNAME_CAPSLOCK "CapsLock" |
1215 | | #define NS_DOM_KEYNAME_CONTROL "Control" |
1216 | | #define NS_DOM_KEYNAME_FN "Fn" |
1217 | | #define NS_DOM_KEYNAME_FNLOCK "FnLock" |
1218 | | #define NS_DOM_KEYNAME_META "Meta" |
1219 | | #define NS_DOM_KEYNAME_NUMLOCK "NumLock" |
1220 | | #define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock" |
1221 | | #define NS_DOM_KEYNAME_SHIFT "Shift" |
1222 | | #define NS_DOM_KEYNAME_SYMBOL "Symbol" |
1223 | | #define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock" |
1224 | | #define NS_DOM_KEYNAME_OS "OS" |
1225 | | |
1226 | | /****************************************************************************** |
1227 | | * mozilla::Modifiers |
1228 | | ******************************************************************************/ |
1229 | | |
1230 | | typedef uint16_t Modifiers; |
1231 | | |
1232 | | class MOZ_STACK_CLASS GetModifiersName final : public nsAutoCString |
1233 | | { |
1234 | | public: |
1235 | | explicit GetModifiersName(Modifiers aModifiers) |
1236 | 0 | { |
1237 | 0 | if (aModifiers & MODIFIER_ALT) { |
1238 | 0 | AssignLiteral(NS_DOM_KEYNAME_ALT); |
1239 | 0 | } |
1240 | 0 | if (aModifiers & MODIFIER_ALTGRAPH) { |
1241 | 0 | MaybeAppendSeparator(); |
1242 | 0 | AppendLiteral(NS_DOM_KEYNAME_ALTGRAPH); |
1243 | 0 | } |
1244 | 0 | if (aModifiers & MODIFIER_CAPSLOCK) { |
1245 | 0 | MaybeAppendSeparator(); |
1246 | 0 | AppendLiteral(NS_DOM_KEYNAME_CAPSLOCK); |
1247 | 0 | } |
1248 | 0 | if (aModifiers & MODIFIER_CONTROL) { |
1249 | 0 | MaybeAppendSeparator(); |
1250 | 0 | AppendLiteral(NS_DOM_KEYNAME_CONTROL); |
1251 | 0 | } |
1252 | 0 | if (aModifiers & MODIFIER_FN) { |
1253 | 0 | MaybeAppendSeparator(); |
1254 | 0 | AppendLiteral(NS_DOM_KEYNAME_FN); |
1255 | 0 | } |
1256 | 0 | if (aModifiers & MODIFIER_FNLOCK) { |
1257 | 0 | MaybeAppendSeparator(); |
1258 | 0 | AppendLiteral(NS_DOM_KEYNAME_FNLOCK); |
1259 | 0 | } |
1260 | 0 | if (aModifiers & MODIFIER_META) { |
1261 | 0 | MaybeAppendSeparator(); |
1262 | 0 | AppendLiteral(NS_DOM_KEYNAME_META); |
1263 | 0 | } |
1264 | 0 | if (aModifiers & MODIFIER_NUMLOCK) { |
1265 | 0 | MaybeAppendSeparator(); |
1266 | 0 | AppendLiteral(NS_DOM_KEYNAME_NUMLOCK); |
1267 | 0 | } |
1268 | 0 | if (aModifiers & MODIFIER_SCROLLLOCK) { |
1269 | 0 | MaybeAppendSeparator(); |
1270 | 0 | AppendLiteral(NS_DOM_KEYNAME_SCROLLLOCK); |
1271 | 0 | } |
1272 | 0 | if (aModifiers & MODIFIER_SHIFT) { |
1273 | 0 | MaybeAppendSeparator(); |
1274 | 0 | AppendLiteral(NS_DOM_KEYNAME_SHIFT); |
1275 | 0 | } |
1276 | 0 | if (aModifiers & MODIFIER_SYMBOL) { |
1277 | 0 | MaybeAppendSeparator(); |
1278 | 0 | AppendLiteral(NS_DOM_KEYNAME_SYMBOL); |
1279 | 0 | } |
1280 | 0 | if (aModifiers & MODIFIER_SYMBOLLOCK) { |
1281 | 0 | MaybeAppendSeparator(); |
1282 | 0 | AppendLiteral(NS_DOM_KEYNAME_SYMBOLLOCK); |
1283 | 0 | } |
1284 | 0 | if (aModifiers & MODIFIER_OS) { |
1285 | 0 | MaybeAppendSeparator(); |
1286 | 0 | AppendLiteral(NS_DOM_KEYNAME_OS); |
1287 | 0 | } |
1288 | 0 | if (IsEmpty()) { |
1289 | 0 | AssignLiteral("none"); |
1290 | 0 | } |
1291 | 0 | } |
1292 | | |
1293 | | private: |
1294 | | void MaybeAppendSeparator() |
1295 | 0 | { |
1296 | 0 | if (!IsEmpty()) { |
1297 | 0 | AppendLiteral(" | "); |
1298 | 0 | } |
1299 | 0 | } |
1300 | | }; |
1301 | | |
1302 | | /****************************************************************************** |
1303 | | * mozilla::WidgetInputEvent |
1304 | | ******************************************************************************/ |
1305 | | |
1306 | | class WidgetInputEvent : public WidgetGUIEvent |
1307 | | { |
1308 | | protected: |
1309 | | WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget, |
1310 | | EventClassID aEventClassID) |
1311 | | : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID) |
1312 | | , mModifiers(0) |
1313 | 0 | { |
1314 | 0 | } |
1315 | | |
1316 | | WidgetInputEvent() |
1317 | | : mModifiers(0) |
1318 | 0 | { |
1319 | 0 | } |
1320 | | |
1321 | | public: |
1322 | 0 | virtual WidgetInputEvent* AsInputEvent() override { return this; } |
1323 | | |
1324 | | WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget) |
1325 | | : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eInputEventClass) |
1326 | | , mModifiers(0) |
1327 | 0 | { |
1328 | 0 | } |
1329 | | |
1330 | | virtual WidgetEvent* Duplicate() const override |
1331 | 0 | { |
1332 | 0 | MOZ_ASSERT(mClass == eInputEventClass, |
1333 | 0 | "Duplicate() must be overridden by sub class"); |
1334 | 0 | // Not copying widget, it is a weak reference. |
1335 | 0 | WidgetInputEvent* result = new WidgetInputEvent(false, mMessage, nullptr); |
1336 | 0 | result->AssignInputEventData(*this, true); |
1337 | 0 | result->mFlags = mFlags; |
1338 | 0 | return result; |
1339 | 0 | } |
1340 | | |
1341 | | |
1342 | | /** |
1343 | | * Returns a modifier of "Accel" virtual modifier which is used for shortcut |
1344 | | * key. |
1345 | | */ |
1346 | | static Modifier AccelModifier(); |
1347 | | |
1348 | | /** |
1349 | | * GetModifier() returns a modifier flag which is activated by aDOMKeyName. |
1350 | | */ |
1351 | | static Modifier GetModifier(const nsAString& aDOMKeyName); |
1352 | | |
1353 | | // true indicates the accel key on the environment is down |
1354 | | bool IsAccel() const |
1355 | 0 | { |
1356 | 0 | return ((mModifiers & AccelModifier()) != 0); |
1357 | 0 | } |
1358 | | |
1359 | | // true indicates the shift key is down |
1360 | | bool IsShift() const |
1361 | 0 | { |
1362 | 0 | return ((mModifiers & MODIFIER_SHIFT) != 0); |
1363 | 0 | } |
1364 | | // true indicates the control key is down |
1365 | | bool IsControl() const |
1366 | 0 | { |
1367 | 0 | return ((mModifiers & MODIFIER_CONTROL) != 0); |
1368 | 0 | } |
1369 | | // true indicates the alt key is down |
1370 | | bool IsAlt() const |
1371 | 0 | { |
1372 | 0 | return ((mModifiers & MODIFIER_ALT) != 0); |
1373 | 0 | } |
1374 | | // true indicates the meta key is down (or, on Mac, the Command key) |
1375 | | bool IsMeta() const |
1376 | 0 | { |
1377 | 0 | return ((mModifiers & MODIFIER_META) != 0); |
1378 | 0 | } |
1379 | | // true indicates the win key is down on Windows. Or the Super or Hyper key |
1380 | | // is down on Linux. |
1381 | | bool IsOS() const |
1382 | 0 | { |
1383 | 0 | return ((mModifiers & MODIFIER_OS) != 0); |
1384 | 0 | } |
1385 | | // true indicates the alt graph key is down |
1386 | | // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah() |
1387 | | // return true. |
1388 | | bool IsAltGraph() const |
1389 | 0 | { |
1390 | 0 | return ((mModifiers & MODIFIER_ALTGRAPH) != 0); |
1391 | 0 | } |
1392 | | // true indicates the CapLock LED is turn on. |
1393 | | bool IsCapsLocked() const |
1394 | 0 | { |
1395 | 0 | return ((mModifiers & MODIFIER_CAPSLOCK) != 0); |
1396 | 0 | } |
1397 | | // true indicates the NumLock LED is turn on. |
1398 | | bool IsNumLocked() const |
1399 | 0 | { |
1400 | 0 | return ((mModifiers & MODIFIER_NUMLOCK) != 0); |
1401 | 0 | } |
1402 | | // true indicates the ScrollLock LED is turn on. |
1403 | | bool IsScrollLocked() const |
1404 | 0 | { |
1405 | 0 | return ((mModifiers & MODIFIER_SCROLLLOCK) != 0); |
1406 | 0 | } |
1407 | | |
1408 | | // true indicates the Fn key is down, but this is not supported by native |
1409 | | // key event on any platform. |
1410 | | bool IsFn() const |
1411 | 0 | { |
1412 | 0 | return ((mModifiers & MODIFIER_FN) != 0); |
1413 | 0 | } |
1414 | | // true indicates the FnLock LED is turn on, but we don't know such |
1415 | | // keyboards nor platforms. |
1416 | | bool IsFnLocked() const |
1417 | 0 | { |
1418 | 0 | return ((mModifiers & MODIFIER_FNLOCK) != 0); |
1419 | 0 | } |
1420 | | // true indicates the Symbol is down, but this is not supported by native |
1421 | | // key event on any platforms. |
1422 | | bool IsSymbol() const |
1423 | 0 | { |
1424 | 0 | return ((mModifiers & MODIFIER_SYMBOL) != 0); |
1425 | 0 | } |
1426 | | // true indicates the SymbolLock LED is turn on, but we don't know such |
1427 | | // keyboards nor platforms. |
1428 | | bool IsSymbolLocked() const |
1429 | 0 | { |
1430 | 0 | return ((mModifiers & MODIFIER_SYMBOLLOCK) != 0); |
1431 | 0 | } |
1432 | | |
1433 | | void InitBasicModifiers(bool aCtrlKey, |
1434 | | bool aAltKey, |
1435 | | bool aShiftKey, |
1436 | | bool aMetaKey) |
1437 | 0 | { |
1438 | 0 | mModifiers = 0; |
1439 | 0 | if (aCtrlKey) { |
1440 | 0 | mModifiers |= MODIFIER_CONTROL; |
1441 | 0 | } |
1442 | 0 | if (aAltKey) { |
1443 | 0 | mModifiers |= MODIFIER_ALT; |
1444 | 0 | } |
1445 | 0 | if (aShiftKey) { |
1446 | 0 | mModifiers |= MODIFIER_SHIFT; |
1447 | 0 | } |
1448 | 0 | if (aMetaKey) { |
1449 | 0 | mModifiers |= MODIFIER_META; |
1450 | 0 | } |
1451 | 0 | } |
1452 | | |
1453 | | Modifiers mModifiers; |
1454 | | |
1455 | | void AssignInputEventData(const WidgetInputEvent& aEvent, bool aCopyTargets) |
1456 | 0 | { |
1457 | 0 | AssignGUIEventData(aEvent, aCopyTargets); |
1458 | 0 |
|
1459 | 0 | mModifiers = aEvent.mModifiers; |
1460 | 0 | } |
1461 | | }; |
1462 | | |
1463 | | /****************************************************************************** |
1464 | | * mozilla::InternalUIEvent |
1465 | | * |
1466 | | * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent? |
1467 | | ******************************************************************************/ |
1468 | | |
1469 | | class InternalUIEvent : public WidgetGUIEvent |
1470 | | { |
1471 | | protected: |
1472 | | InternalUIEvent() |
1473 | | : mDetail(0) |
1474 | | , mCausedByUntrustedEvent(false) |
1475 | 0 | { |
1476 | 0 | } |
1477 | | |
1478 | | InternalUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget, |
1479 | | EventClassID aEventClassID) |
1480 | | : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID) |
1481 | | , mDetail(0) |
1482 | | , mCausedByUntrustedEvent(false) |
1483 | 0 | { |
1484 | 0 | } |
1485 | | |
1486 | | InternalUIEvent(bool aIsTrusted, EventMessage aMessage, |
1487 | | EventClassID aEventClassID) |
1488 | | : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, aEventClassID) |
1489 | | , mDetail(0) |
1490 | | , mCausedByUntrustedEvent(false) |
1491 | 0 | { |
1492 | 0 | } |
1493 | | |
1494 | | public: |
1495 | 0 | virtual InternalUIEvent* AsUIEvent() override { return this; } |
1496 | | |
1497 | | /** |
1498 | | * If the UIEvent is caused by another event (e.g., click event), |
1499 | | * aEventCausesThisEvent should be the event. If there is no such event, |
1500 | | * this should be nullptr. |
1501 | | */ |
1502 | | InternalUIEvent(bool aIsTrusted, EventMessage aMessage, |
1503 | | const WidgetEvent* aEventCausesThisEvent) |
1504 | | : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, eUIEventClass) |
1505 | | , mDetail(0) |
1506 | | , mCausedByUntrustedEvent( |
1507 | | aEventCausesThisEvent && !aEventCausesThisEvent->IsTrusted()) |
1508 | 0 | { |
1509 | 0 | } |
1510 | | |
1511 | | virtual WidgetEvent* Duplicate() const override |
1512 | 0 | { |
1513 | 0 | MOZ_ASSERT(mClass == eUIEventClass, |
1514 | 0 | "Duplicate() must be overridden by sub class"); |
1515 | 0 | InternalUIEvent* result = new InternalUIEvent(false, mMessage, nullptr); |
1516 | 0 | result->AssignUIEventData(*this, true); |
1517 | 0 | result->mFlags = mFlags; |
1518 | 0 | return result; |
1519 | 0 | } |
1520 | | |
1521 | | int32_t mDetail; |
1522 | | // mCausedByUntrustedEvent is true if the event is caused by untrusted event. |
1523 | | bool mCausedByUntrustedEvent; |
1524 | | |
1525 | | // If you check the event is a trusted event and NOT caused by an untrusted |
1526 | | // event, IsTrustable() returns what you expected. |
1527 | | bool IsTrustable() const |
1528 | 0 | { |
1529 | 0 | return IsTrusted() && !mCausedByUntrustedEvent; |
1530 | 0 | } |
1531 | | |
1532 | | void AssignUIEventData(const InternalUIEvent& aEvent, bool aCopyTargets) |
1533 | 0 | { |
1534 | 0 | AssignGUIEventData(aEvent, aCopyTargets); |
1535 | 0 |
|
1536 | 0 | mDetail = aEvent.mDetail; |
1537 | 0 | mCausedByUntrustedEvent = aEvent.mCausedByUntrustedEvent; |
1538 | 0 | } |
1539 | | }; |
1540 | | |
1541 | | } // namespace mozilla |
1542 | | |
1543 | | #endif // mozilla_BasicEvents_h__ |