dom/events/EventStateManager.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:90d30cc229ba
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_EventStateManager_h_
7 #define mozilla_EventStateManager_h_
8
9 #include "mozilla/EventForwards.h"
10 #include "mozilla/TypedEnum.h"
11
12 #include "nsIObserver.h"
13 #include "nsWeakReference.h"
14 #include "nsCOMPtr.h"
15 #include "nsCOMArray.h"
16 #include "nsCycleCollectionParticipant.h"
17 #include "mozilla/TimeStamp.h"
18 #include "nsIFrame.h"
19 #include "Units.h"
20
21 class nsFrameLoader;
22 class nsIContent;
23 class nsIDocument;
24 class nsIDocShell;
25 class nsIDocShellTreeItem;
26 class imgIContainer;
27 class EnterLeaveDispatcher;
28 class nsIMarkupDocumentViewer;
29 class nsIScrollableFrame;
30 class nsITimer;
31 class nsPresContext;
32
33 namespace mozilla {
34
35 class EnterLeaveDispatcher;
36 class EventStates;
37 class IMEContentObserver;
38 class ScrollbarsForWheel;
39 class WheelTransaction;
40
41 namespace dom {
42 class DataTransfer;
43 class TabParent;
44 } // namespace dom
45
46 class OverOutElementsWrapper MOZ_FINAL : public nsISupports
47 {
48 public:
49 OverOutElementsWrapper();
50 ~OverOutElementsWrapper();
51
52 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
53 NS_DECL_CYCLE_COLLECTION_CLASS(OverOutElementsWrapper)
54
55 nsWeakFrame mLastOverFrame;
56
57 nsCOMPtr<nsIContent> mLastOverElement;
58
59 // The last element on which we fired a over event, or null if
60 // the last over event we fired has finished processing.
61 nsCOMPtr<nsIContent> mFirstOverEventElement;
62
63 // The last element on which we fired a out event, or null if
64 // the last out event we fired has finished processing.
65 nsCOMPtr<nsIContent> mFirstOutEventElement;
66 };
67
68 class EventStateManager : public nsSupportsWeakReference,
69 public nsIObserver
70 {
71 friend class mozilla::EnterLeaveDispatcher;
72 friend class mozilla::ScrollbarsForWheel;
73 friend class mozilla::WheelTransaction;
74
75 public:
76 EventStateManager();
77 virtual ~EventStateManager();
78
79 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
80 NS_DECL_NSIOBSERVER
81
82 nsresult Init();
83 nsresult Shutdown();
84
85 /* The PreHandleEvent method is called before event dispatch to either
86 * the DOM or frames. Any processing which must not be prevented or
87 * cancelled should occur here. Any processing which is intended to
88 * be conditional based on either DOM or frame processing should occur in
89 * PostHandleEvent. Any centralized event processing which must occur before
90 * DOM or frame event handling should occur here as well.
91 */
92 nsresult PreHandleEvent(nsPresContext* aPresContext,
93 WidgetEvent* aEvent,
94 nsIFrame* aTargetFrame,
95 nsEventStatus* aStatus);
96
97 /* The PostHandleEvent method should contain all system processing which
98 * should occur conditionally based on DOM or frame processing. It should
99 * also contain any centralized event processing which must occur after
100 * DOM and frame processing.
101 */
102 nsresult PostHandleEvent(nsPresContext* aPresContext,
103 WidgetEvent* aEvent,
104 nsIFrame* aTargetFrame,
105 nsEventStatus* aStatus);
106
107 /**
108 * DispatchLegacyMouseScrollEvents() dispatches NS_MOUSE_SCROLL event and
109 * NS_MOUSE_PIXEL_SCROLL event for compatiblity with old Gecko.
110 */
111 void DispatchLegacyMouseScrollEvents(nsIFrame* aTargetFrame,
112 WidgetWheelEvent* aEvent,
113 nsEventStatus* aStatus);
114
115 void NotifyDestroyPresContext(nsPresContext* aPresContext);
116 void SetPresContext(nsPresContext* aPresContext);
117 void ClearFrameRefs(nsIFrame* aFrame);
118
119 nsIFrame* GetEventTarget();
120 already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);
121
122 /**
123 * Notify that the given NS_EVENT_STATE_* bit has changed for this content.
124 * @param aContent Content which has changed states
125 * @param aState Corresponding state flags such as NS_EVENT_STATE_FOCUS
126 * @return Whether the content was able to change all states. Returns false
127 * if a resulting DOM event causes the content node passed in
128 * to not change states. Note, the frame for the content may
129 * change as a result of the content state change, because of
130 * frame reconstructions that may occur, but this does not
131 * affect the return value.
132 */
133 bool SetContentState(nsIContent* aContent, EventStates aState);
134 void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
135 bool EventStatusOK(WidgetGUIEvent* aEvent);
136
137 /**
138 * EventStateManager stores IMEContentObserver while it's observing contents.
139 * Following mehtods are called by IMEContentObserver when it starts to
140 * observe or stops observing the content.
141 */
142 void OnStartToObserveContent(IMEContentObserver* aIMEContentObserver);
143 void OnStopObservingContent(IMEContentObserver* aIMEContentObserver);
144
145 /**
146 * Register accesskey on the given element. When accesskey is activated then
147 * the element will be notified via nsIContent::PerformAccesskey() method.
148 *
149 * @param aContent the given element
150 * @param aKey accesskey
151 */
152 void RegisterAccessKey(nsIContent* aContent, uint32_t aKey);
153
154 /**
155 * Unregister accesskey for the given element.
156 *
157 * @param aContent the given element
158 * @param aKey accesskey
159 */
160 void UnregisterAccessKey(nsIContent* aContent, uint32_t aKey);
161
162 /**
163 * Get accesskey registered on the given element or 0 if there is none.
164 *
165 * @param aContent the given element (must not be null)
166 * @return registered accesskey
167 */
168 uint32_t GetRegisteredAccessKey(nsIContent* aContent);
169
170 bool GetAccessKeyLabelPrefix(nsAString& aPrefix);
171
172 nsresult SetCursor(int32_t aCursor, imgIContainer* aContainer,
173 bool aHaveHotspot, float aHotspotX, float aHotspotY,
174 nsIWidget* aWidget, bool aLockCursor);
175
176 static void StartHandlingUserInput()
177 {
178 ++sUserInputEventDepth;
179 if (sUserInputEventDepth == 1) {
180 sHandlingInputStart = TimeStamp::Now();
181 }
182 }
183
184 static void StopHandlingUserInput()
185 {
186 --sUserInputEventDepth;
187 if (sUserInputEventDepth == 0) {
188 sHandlingInputStart = TimeStamp();
189 }
190 }
191
192 /**
193 * Returns true if the current code is being executed as a result of user input.
194 * This includes timers or anything else that is initiated from user input.
195 * However, mouse over events are not counted as user input, nor are
196 * page load events. If this method is called from asynchronously executed code,
197 * such as during layout reflows, it will return false. If more time has elapsed
198 * since the user input than is specified by the
199 * dom.event.handling-user-input-time-limit pref (default 1 second), this
200 * function also returns false.
201 */
202 static bool IsHandlingUserInput();
203
204 nsPresContext* GetPresContext() { return mPresContext; }
205
206 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EventStateManager,
207 nsIObserver)
208
209 static nsIDocument* sMouseOverDocument;
210
211 static EventStateManager* GetActiveEventStateManager() { return sActiveESM; }
212
213 // Sets aNewESM to be the active event state manager, and
214 // if aContent is non-null, marks the object as active.
215 static void SetActiveManager(EventStateManager* aNewESM,
216 nsIContent* aContent);
217
218 // Sets the full-screen event state on aElement to aIsFullScreen.
219 static void SetFullScreenState(dom::Element* aElement, bool aIsFullScreen);
220
221 static bool IsRemoteTarget(nsIContent* aTarget);
222 static LayoutDeviceIntPoint GetChildProcessOffset(nsFrameLoader* aFrameLoader,
223 const WidgetEvent& aEvent);
224
225 // Holds the point in screen coords that a mouse event was dispatched to,
226 // before we went into pointer lock mode. This is constantly updated while
227 // the pointer is not locked, but we don't update it while the pointer is
228 // locked. This is used by dom::Event::GetScreenCoords() to make mouse
229 // events' screen coord appear frozen at the last mouse position while
230 // the pointer is locked.
231 static nsIntPoint sLastScreenPoint;
232
233 // Holds the point in client coords of the last mouse event. Used by
234 // dom::Event::GetClientCoords() to make mouse events' client coords appear
235 // frozen at the last mouse position while the pointer is locked.
236 static CSSIntPoint sLastClientPoint;
237
238 static bool sIsPointerLocked;
239 static nsWeakPtr sPointerLockedElement;
240 static nsWeakPtr sPointerLockedDoc;
241
242 protected:
243 /**
244 * Prefs class capsules preference management.
245 */
246 class Prefs
247 {
248 public:
249 static bool KeyCausesActivation() { return sKeyCausesActivation; }
250 static bool ClickHoldContextMenu() { return sClickHoldContextMenu; }
251 static int32_t ChromeAccessModifierMask();
252 static int32_t ContentAccessModifierMask();
253
254 static void Init();
255 static void OnChange(const char* aPrefName, void*);
256 static void Shutdown();
257
258 private:
259 static bool sKeyCausesActivation;
260 static bool sClickHoldContextMenu;
261 static int32_t sGenericAccessModifierKey;
262 static int32_t sChromeAccessModifierMask;
263 static int32_t sContentAccessModifierMask;
264
265 static int32_t GetAccessModifierMask(int32_t aItemType);
266 };
267
268 /**
269 * Get appropriate access modifier mask for the aDocShell. Returns -1 if
270 * access key isn't available.
271 */
272 static int32_t GetAccessModifierMaskFor(nsISupports* aDocShell);
273
274 void UpdateCursor(nsPresContext* aPresContext,
275 WidgetEvent* aEvent,
276 nsIFrame* aTargetFrame,
277 nsEventStatus* aStatus);
278 /**
279 * Turn a GUI mouse/pointer event into a mouse/pointer event targeted at the specified
280 * content. This returns the primary frame for the content (or null
281 * if it goes away during the event).
282 */
283 nsIFrame* DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
284 uint32_t aMessage,
285 nsIContent* aTargetContent,
286 nsIContent* aRelatedContent);
287 /**
288 * Synthesize DOM and frame mouseover and mouseout events from this
289 * MOUSE_MOVE or MOUSE_EXIT event.
290 */
291 void GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent);
292 /**
293 * Tell this ESM and ESMs in parent documents that the mouse is
294 * over some content in this document.
295 */
296 void NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
297 nsIContent* aContent);
298 /**
299 * Tell this ESM and ESMs in affected child documents that the mouse
300 * has exited this document's currently hovered content.
301 * @param aMouseEvent the event that triggered the mouseout
302 * @param aMovingInto the content node we've moved into. This is used to set
303 * the relatedTarget for mouseout events. Also, if it's non-null
304 * NotifyMouseOut will NOT change the current hover content to null;
305 * in that case the caller is responsible for updating hover state.
306 */
307 void NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
308 nsIContent* aMovingInto);
309 void GenerateDragDropEnterExit(nsPresContext* aPresContext,
310 WidgetDragEvent* aDragEvent);
311
312 /**
313 * Return mMouseEnterLeaveHelper or relevant mPointersEnterLeaveHelper elements wrapper.
314 * If mPointersEnterLeaveHelper does not contain wrapper for pointerId it create new one
315 */
316 OverOutElementsWrapper* GetWrapperByEventID(WidgetMouseEvent* aMouseEvent);
317
318 /**
319 * Fire the dragenter and dragexit/dragleave events when the mouse moves to a
320 * new target.
321 *
322 * @param aRelatedTarget relatedTarget to set for the event
323 * @param aTargetContent target to set for the event
324 * @param aTargetFrame target frame for the event
325 */
326 void FireDragEnterOrExit(nsPresContext* aPresContext,
327 WidgetDragEvent* aDragEvent,
328 uint32_t aMsg,
329 nsIContent* aRelatedTarget,
330 nsIContent* aTargetContent,
331 nsWeakFrame& aTargetFrame);
332 /**
333 * Update the initial drag session data transfer with any changes that occur
334 * on cloned data transfer objects used for events.
335 */
336 void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
337
338 nsresult SetClickCount(nsPresContext* aPresContext,
339 WidgetMouseEvent* aEvent,
340 nsEventStatus* aStatus);
341 nsresult CheckForAndDispatchClick(nsPresContext* aPresContext,
342 WidgetMouseEvent* aEvent,
343 nsEventStatus* aStatus);
344 void EnsureDocument(nsPresContext* aPresContext);
345 void FlushPendingEvents(nsPresContext* aPresContext);
346
347 /**
348 * The phases of HandleAccessKey processing. See below.
349 */
350 typedef enum {
351 eAccessKeyProcessingNormal = 0,
352 eAccessKeyProcessingUp,
353 eAccessKeyProcessingDown
354 } ProcessingAccessKeyState;
355
356 /**
357 * Access key handling. If there is registered content for the accesskey
358 * given by the key event and modifier mask then call
359 * content.PerformAccesskey(), otherwise call HandleAccessKey() recursively,
360 * on descendant docshells first, then on the ancestor (with |aBubbledFrom|
361 * set to the docshell associated with |this|), until something matches.
362 *
363 * @param aPresContext the presentation context
364 * @param aEvent the key event
365 * @param aStatus the event status
366 * @param aBubbledFrom is used by an ancestor to avoid calling HandleAccessKey()
367 * on the child the call originally came from, i.e. this is the child
368 * that recursively called us in its Up phase. The initial caller
369 * passes |nullptr| here. This is to avoid an infinite loop.
370 * @param aAccessKeyState Normal, Down or Up processing phase (see enums
371 * above). The initial event receiver uses 'normal', then 'down' when
372 * processing children and Up when recursively calling its ancestor.
373 * @param aModifierMask modifier mask for the key event
374 */
375 void HandleAccessKey(nsPresContext* aPresContext,
376 WidgetKeyboardEvent* aEvent,
377 nsEventStatus* aStatus,
378 nsIDocShellTreeItem* aBubbledFrom,
379 ProcessingAccessKeyState aAccessKeyState,
380 int32_t aModifierMask);
381
382 bool ExecuteAccessKey(nsTArray<uint32_t>& aAccessCharCodes,
383 bool aIsTrustedEvent);
384
385 //---------------------------------------------
386 // DocShell Focus Traversal Methods
387 //---------------------------------------------
388
389 nsIContent* GetFocusedContent();
390 bool IsShellVisible(nsIDocShell* aShell);
391
392 // These functions are for mousewheel and pixel scrolling
393
394 class WheelPrefs
395 {
396 public:
397 static WheelPrefs* GetInstance();
398 static void Shutdown();
399
400 /**
401 * ApplyUserPrefsToDelta() overrides the wheel event's delta values with
402 * user prefs.
403 */
404 void ApplyUserPrefsToDelta(WidgetWheelEvent* aEvent);
405
406 /**
407 * If ApplyUserPrefsToDelta() changed the delta values with customized
408 * prefs, the overflowDelta values would be inflated.
409 * CancelApplyingUserPrefsFromOverflowDelta() cancels the inflation.
410 */
411 void CancelApplyingUserPrefsFromOverflowDelta(WidgetWheelEvent* aEvent);
412
413 /**
414 * Computes the default action for the aEvent with the prefs.
415 */
416 enum Action MOZ_ENUM_TYPE(uint8_t)
417 {
418 ACTION_NONE = 0,
419 ACTION_SCROLL,
420 ACTION_HISTORY,
421 ACTION_ZOOM,
422 ACTION_LAST = ACTION_ZOOM
423 };
424 Action ComputeActionFor(WidgetWheelEvent* aEvent);
425
426 /**
427 * NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
428 * computed the lineOrPageDelta values.
429 */
430 bool NeedToComputeLineOrPageDelta(WidgetWheelEvent* aEvent);
431
432 /**
433 * IsOverOnePageScrollAllowed*() checks whether wheel scroll amount should
434 * be rounded down to the page width/height (false) or not (true).
435 */
436 bool IsOverOnePageScrollAllowedX(WidgetWheelEvent* aEvent);
437 bool IsOverOnePageScrollAllowedY(WidgetWheelEvent* aEvent);
438
439 private:
440 WheelPrefs();
441 ~WheelPrefs();
442
443 static void OnPrefChanged(const char* aPrefName, void* aClosure);
444
445 enum Index
446 {
447 INDEX_DEFAULT = 0,
448 INDEX_ALT,
449 INDEX_CONTROL,
450 INDEX_META,
451 INDEX_SHIFT,
452 INDEX_OS,
453 COUNT_OF_MULTIPLIERS
454 };
455
456 /**
457 * GetIndexFor() returns the index of the members which should be used for
458 * the aEvent. When only one modifier key of MODIFIER_ALT,
459 * MODIFIER_CONTROL, MODIFIER_META, MODIFIER_SHIFT or MODIFIER_OS is
460 * pressed, returns the index for the modifier. Otherwise, this return the
461 * default index which is used at either no modifier key is pressed or
462 * two or modifier keys are pressed.
463 */
464 Index GetIndexFor(WidgetWheelEvent* aEvent);
465
466 /**
467 * GetPrefNameBase() returns the base pref name for aEvent.
468 * It's decided by GetModifierForPref() which modifier should be used for
469 * the aEvent.
470 *
471 * @param aBasePrefName The result, must be "mousewheel.with_*." or
472 * "mousewheel.default.".
473 */
474 void GetBasePrefName(Index aIndex, nsACString& aBasePrefName);
475
476 void Init(Index aIndex);
477
478 void Reset();
479
480 /**
481 * If the abosolute values of mMultiplierX and/or mMultiplierY are equals or
482 * larger than this value, the computed scroll amount isn't rounded down to
483 * the page width or height.
484 */
485 enum {
486 MIN_MULTIPLIER_VALUE_ALLOWING_OVER_ONE_PAGE_SCROLL = 1000
487 };
488
489 bool mInit[COUNT_OF_MULTIPLIERS];
490 double mMultiplierX[COUNT_OF_MULTIPLIERS];
491 double mMultiplierY[COUNT_OF_MULTIPLIERS];
492 double mMultiplierZ[COUNT_OF_MULTIPLIERS];
493 Action mActions[COUNT_OF_MULTIPLIERS];
494 /**
495 * action values overridden by .override_x pref.
496 * If an .override_x value is -1, same as the
497 * corresponding mActions value.
498 */
499 Action mOverriddenActionsX[COUNT_OF_MULTIPLIERS];
500
501 static WheelPrefs* sInstance;
502 };
503
504 /**
505 * DeltaDirection is used for specifying whether the called method should
506 * handle vertical delta or horizontal delta.
507 * This is clearer than using bool.
508 */
509 enum DeltaDirection
510 {
511 DELTA_DIRECTION_X = 0,
512 DELTA_DIRECTION_Y
513 };
514
515 struct MOZ_STACK_CLASS EventState
516 {
517 bool mDefaultPrevented;
518 bool mDefaultPreventedByContent;
519
520 EventState() :
521 mDefaultPrevented(false), mDefaultPreventedByContent(false)
522 {
523 }
524 };
525
526 /**
527 * SendLineScrollEvent() dispatches a DOMMouseScroll event for the
528 * WidgetWheelEvent. This method shouldn't be called for non-trusted
529 * wheel event because it's not necessary for compatiblity.
530 *
531 * @param aTargetFrame The event target of wheel event.
532 * @param aEvent The original Wheel event.
533 * @param aState The event which should be set to the dispatching
534 * event. This also returns the dispatched event
535 * state.
536 * @param aDelta The delta value of the event.
537 * @param aDeltaDirection The X/Y direction of dispatching event.
538 */
539 void SendLineScrollEvent(nsIFrame* aTargetFrame,
540 WidgetWheelEvent* aEvent,
541 EventState& aState,
542 int32_t aDelta,
543 DeltaDirection aDeltaDirection);
544
545 /**
546 * SendPixelScrollEvent() dispatches a MozMousePixelScroll event for the
547 * WidgetWheelEvent. This method shouldn't be called for non-trusted
548 * wheel event because it's not necessary for compatiblity.
549 *
550 * @param aTargetFrame The event target of wheel event.
551 * @param aEvent The original Wheel event.
552 * @param aState The event which should be set to the dispatching
553 * event. This also returns the dispatched event
554 * state.
555 * @param aPixelDelta The delta value of the event.
556 * @param aDeltaDirection The X/Y direction of dispatching event.
557 */
558 void SendPixelScrollEvent(nsIFrame* aTargetFrame,
559 WidgetWheelEvent* aEvent,
560 EventState& aState,
561 int32_t aPixelDelta,
562 DeltaDirection aDeltaDirection);
563
564 /**
565 * ComputeScrollTarget() returns the scrollable frame which should be
566 * scrolled.
567 *
568 * @param aTargetFrame The event target of the wheel event.
569 * @param aEvent The handling mouse wheel event.
570 * @param aOptions The options for finding the scroll target.
571 * Callers should use COMPUTE_*.
572 * @return The scrollable frame which should be scrolled.
573 */
574 // These flags are used in ComputeScrollTarget(). Callers should use
575 // COMPUTE_*.
576 enum
577 {
578 PREFER_MOUSE_WHEEL_TRANSACTION = 1,
579 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS = 2,
580 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS = 4,
581 START_FROM_PARENT = 8
582 };
583 enum ComputeScrollTargetOptions
584 {
585 // At computing scroll target for legacy mouse events, we should return
586 // first scrollable element even when it's not scrollable to the direction.
587 COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET = 0,
588 // Default action prefers the scrolled element immediately before if it's
589 // still under the mouse cursor. Otherwise, it prefers the nearest
590 // scrollable ancestor which will be scrolled actually.
591 COMPUTE_DEFAULT_ACTION_TARGET =
592 (PREFER_MOUSE_WHEEL_TRANSACTION |
593 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS |
594 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS),
595 // Look for the nearest scrollable ancestor which can be scrollable with
596 // aEvent.
597 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS =
598 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS | START_FROM_PARENT),
599 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS =
600 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT)
601 };
602 nsIScrollableFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
603 WidgetWheelEvent* aEvent,
604 ComputeScrollTargetOptions aOptions);
605
606 nsIScrollableFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
607 double aDirectionX,
608 double aDirectionY,
609 WidgetWheelEvent* aEvent,
610 ComputeScrollTargetOptions aOptions);
611
612 /**
613 * GetScrollAmount() returns the scroll amount in app uints of one line or
614 * one page. If the wheel event scrolls a page, returns the page width and
615 * height. Otherwise, returns line height for both its width and height.
616 *
617 * @param aScrollableFrame A frame which will be scrolled by the event.
618 * The result of ComputeScrollTarget() is
619 * expected for this value.
620 * This can be nullptr if there is no scrollable
621 * frame. Then, this method uses root frame's
622 * line height or visible area's width and height.
623 */
624 nsSize GetScrollAmount(nsPresContext* aPresContext,
625 WidgetWheelEvent* aEvent,
626 nsIScrollableFrame* aScrollableFrame);
627
628 /**
629 * DoScrollText() scrolls the scrollable frame for aEvent.
630 */
631 void DoScrollText(nsIScrollableFrame* aScrollableFrame,
632 WidgetWheelEvent* aEvent);
633
634 void DoScrollHistory(int32_t direction);
635 void DoScrollZoom(nsIFrame *aTargetFrame, int32_t adjustment);
636 nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);
637 nsresult ChangeTextSize(int32_t change);
638 nsresult ChangeFullZoom(int32_t change);
639
640 /**
641 * DeltaAccumulator class manages delta values for dispatching DOMMouseScroll
642 * event. If wheel events are caused by pixel scroll only devices or
643 * the delta values are customized by prefs, this class stores the delta
644 * values and set lineOrPageDelta values.
645 */
646 class DeltaAccumulator
647 {
648 public:
649 static DeltaAccumulator* GetInstance()
650 {
651 if (!sInstance) {
652 sInstance = new DeltaAccumulator;
653 }
654 return sInstance;
655 }
656
657 static void Shutdown()
658 {
659 delete sInstance;
660 sInstance = nullptr;
661 }
662
663 bool IsInTransaction() { return mHandlingDeltaMode != UINT32_MAX; }
664
665 /**
666 * InitLineOrPageDelta() stores pixel delta values of WidgetWheelEvents
667 * which are caused if it's needed. And if the accumulated delta becomes a
668 * line height, sets lineOrPageDeltaX and lineOrPageDeltaY automatically.
669 */
670 void InitLineOrPageDelta(nsIFrame* aTargetFrame,
671 EventStateManager* aESM,
672 WidgetWheelEvent* aEvent);
673
674 /**
675 * Reset() resets all members.
676 */
677 void Reset();
678
679 /**
680 * ComputeScrollAmountForDefaultAction() computes the default action's
681 * scroll amount in device pixels with mPendingScrollAmount*.
682 */
683 nsIntPoint ComputeScrollAmountForDefaultAction(
684 WidgetWheelEvent* aEvent,
685 const nsIntSize& aScrollAmountInDevPixels);
686
687 private:
688 DeltaAccumulator() :
689 mX(0.0), mY(0.0), mPendingScrollAmountX(0.0), mPendingScrollAmountY(0.0),
690 mHandlingDeltaMode(UINT32_MAX), mHandlingPixelOnlyDevice(false)
691 {
692 }
693
694 double mX;
695 double mY;
696
697 // When default action of a wheel event is scroll but some delta values
698 // are ignored because the computed amount values are not integer, the
699 // fractional values are saved by these members.
700 double mPendingScrollAmountX;
701 double mPendingScrollAmountY;
702
703 TimeStamp mLastTime;
704
705 uint32_t mHandlingDeltaMode;
706 bool mHandlingPixelOnlyDevice;
707
708 static DeltaAccumulator* sInstance;
709 };
710
711 // end mousewheel functions
712
713 /*
714 * When a touch gesture is about to start, this function determines what
715 * kind of gesture interaction we will want to use, based on what is
716 * underneath the initial touch point.
717 * Currently it decides between panning (finger scrolling) or dragging
718 * the target element, as well as the orientation to trigger panning and
719 * display visual boundary feedback. The decision is stored back in aEvent.
720 */
721 void DecideGestureEvent(WidgetGestureNotifyEvent* aEvent,
722 nsIFrame* targetFrame);
723
724 // routines for the d&d gesture tracking state machine
725 void BeginTrackingDragGesture(nsPresContext* aPresContext,
726 WidgetMouseEvent* aDownEvent,
727 nsIFrame* aDownFrame);
728 void StopTrackingDragGesture();
729 void GenerateDragGesture(nsPresContext* aPresContext,
730 WidgetMouseEvent* aEvent);
731
732 /**
733 * Determine which node the drag should be targeted at.
734 * This is either the node clicked when there is a selection, or, for HTML,
735 * the element with a draggable property set to true.
736 *
737 * aSelectionTarget - target to check for selection
738 * aDataTransfer - data transfer object that will contain the data to drag
739 * aSelection - [out] set to the selection to be dragged
740 * aTargetNode - [out] the draggable node, or null if there isn't one
741 */
742 void DetermineDragTarget(nsPIDOMWindow* aWindow,
743 nsIContent* aSelectionTarget,
744 dom::DataTransfer* aDataTransfer,
745 nsISelection** aSelection,
746 nsIContent** aTargetNode);
747
748 /*
749 * Perform the default handling for the dragstart/draggesture event and set up a
750 * drag for aDataTransfer if it contains any data. Returns true if a drag has
751 * started.
752 *
753 * aDragEvent - the dragstart/draggesture event
754 * aDataTransfer - the data transfer that holds the data to be dragged
755 * aDragTarget - the target of the drag
756 * aSelection - the selection to be dragged
757 */
758 bool DoDefaultDragStart(nsPresContext* aPresContext,
759 WidgetDragEvent* aDragEvent,
760 dom::DataTransfer* aDataTransfer,
761 nsIContent* aDragTarget,
762 nsISelection* aSelection);
763
764 bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nullptr; }
765 /**
766 * Set the fields of aEvent to reflect the mouse position and modifier keys
767 * that were set when the user first pressed the mouse button (stored by
768 * BeginTrackingDragGesture). aEvent->widget must be
769 * mCurrentTarget->GetNearestWidget().
770 */
771 void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);
772
773 nsresult DoContentCommandEvent(WidgetContentCommandEvent* aEvent);
774 nsresult DoContentCommandScrollEvent(WidgetContentCommandEvent* aEvent);
775
776 void DoQuerySelectedText(WidgetQueryContentEvent* aEvent);
777
778 bool RemoteQueryContentEvent(WidgetEvent* aEvent);
779 dom::TabParent *GetCrossProcessTarget();
780 bool IsTargetCrossProcess(WidgetGUIEvent* aEvent);
781
782 bool DispatchCrossProcessEvent(WidgetEvent* aEvent,
783 nsFrameLoader* aRemote,
784 nsEventStatus *aStatus);
785 bool HandleCrossProcessEvent(WidgetEvent* aEvent,
786 nsIFrame* aTargetFrame,
787 nsEventStatus* aStatus);
788
789 void ReleaseCurrentIMEContentObserver();
790
791 private:
792 static inline void DoStateChange(dom::Element* aElement,
793 EventStates aState, bool aAddState);
794 static inline void DoStateChange(nsIContent* aContent, EventStates aState,
795 bool aAddState);
796 static void UpdateAncestorState(nsIContent* aStartNode,
797 nsIContent* aStopBefore,
798 EventStates aState,
799 bool aAddState);
800 static PLDHashOperator ResetLastOverForContent(const uint32_t& aIdx,
801 nsRefPtr<OverOutElementsWrapper>& aChunk,
802 void* aClosure);
803
804 int32_t mLockCursor;
805
806 // Last mouse event refPoint (the offset from the widget's origin in
807 // device pixels) when mouse was locked, used to restore mouse position
808 // after unlocking.
809 LayoutDeviceIntPoint mPreLockPoint;
810
811 // Stores the refPoint of the last synthetic mouse move we dispatched
812 // to re-center the mouse when we were pointer locked. If this is (-1,-1) it
813 // means we've not recently dispatched a centering event. We use this to
814 // detect when we receive the synth event, so we can cancel and not send it
815 // to content.
816 static LayoutDeviceIntPoint sSynthCenteringPoint;
817
818 nsWeakFrame mCurrentTarget;
819 nsCOMPtr<nsIContent> mCurrentTargetContent;
820 static nsWeakFrame sLastDragOverFrame;
821
822 // Stores the refPoint (the offset from the widget's origin in device
823 // pixels) of the last mouse event.
824 static LayoutDeviceIntPoint sLastRefPoint;
825
826 // member variables for the d&d gesture state machine
827 LayoutDeviceIntPoint mGestureDownPoint; // screen coordinates
828 // The content to use as target if we start a d&d (what we drag).
829 nsCOMPtr<nsIContent> mGestureDownContent;
830 // The content of the frame where the mouse-down event occurred. It's the same
831 // as the target in most cases but not always - for example when dragging
832 // an <area> of an image map this is the image. (bug 289667)
833 nsCOMPtr<nsIContent> mGestureDownFrameOwner;
834 // State of keys when the original gesture-down happened
835 Modifiers mGestureModifiers;
836 uint16_t mGestureDownButtons;
837
838 nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
839 nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
840 nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
841 nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
842 nsCOMPtr<nsIContent> mLastRightMouseDownContent;
843 nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
844
845 nsCOMPtr<nsIContent> mActiveContent;
846 nsCOMPtr<nsIContent> mHoverContent;
847 static nsCOMPtr<nsIContent> sDragOverContent;
848 nsCOMPtr<nsIContent> mURLTargetContent;
849
850 nsPresContext* mPresContext; // Not refcnted
851 nsCOMPtr<nsIDocument> mDocument; // Doesn't necessarily need to be owner
852
853 nsRefPtr<IMEContentObserver> mIMEContentObserver;
854
855 uint32_t mLClickCount;
856 uint32_t mMClickCount;
857 uint32_t mRClickCount;
858
859 bool m_haveShutdown;
860
861 // Time at which we began handling user input.
862 static TimeStamp sHandlingInputStart;
863
864 nsRefPtr<OverOutElementsWrapper> mMouseEnterLeaveHelper;
865 nsRefPtrHashtable<nsUint32HashKey, OverOutElementsWrapper> mPointersEnterLeaveHelper;
866
867 public:
868 static nsresult UpdateUserActivityTimer(void);
869 // Array for accesskey support
870 nsCOMArray<nsIContent> mAccessKeys;
871
872 static int32_t sUserInputEventDepth;
873
874 static bool sNormalLMouseEventInProcess;
875
876 static EventStateManager* sActiveESM;
877
878 static void ClearGlobalActiveContent(EventStateManager* aClearer);
879
880 // Functions used for click hold context menus
881 nsCOMPtr<nsITimer> mClickHoldTimer;
882 void CreateClickHoldTimer(nsPresContext* aPresContext,
883 nsIFrame* aDownFrame,
884 WidgetGUIEvent* aMouseDownEvent);
885 void KillClickHoldTimer();
886 void FireContextClick();
887
888 void SetPointerLock(nsIWidget* aWidget, nsIContent* aElement) ;
889 static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ;
890 };
891
892 /**
893 * This class is used while processing real user input. During this time, popups
894 * are allowed. For mousedown events, mouse capturing is also permitted.
895 */
896 class AutoHandlingUserInputStatePusher
897 {
898 public:
899 AutoHandlingUserInputStatePusher(bool aIsHandlingUserInput,
900 WidgetEvent* aEvent,
901 nsIDocument* aDocument);
902 ~AutoHandlingUserInputStatePusher();
903
904 protected:
905 bool mIsHandlingUserInput;
906 bool mIsMouseDown;
907 bool mResetFMMouseDownState;
908
909 private:
910 // Hide so that this class can only be stack-allocated
911 static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nullptr; }
912 static void operator delete(void* /*memory*/) {}
913 };
914
915 } // namespace mozilla
916
917 // Click and double-click events need to be handled even for content that
918 // has no frame. This is required for Web compatibility.
919 #define NS_EVENT_NEEDS_FRAME(event) \
920 (!(event)->HasPluginActivationEventMessage() && \
921 (event)->message != NS_MOUSE_CLICK && \
922 (event)->message != NS_MOUSE_DOUBLECLICK)
923
924 #endif // mozilla_EventStateManager_h_

mercurial