1 /*
2  * Copyright (C) 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLER_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLER_H_
28 
29 #include "base/macros.h"
30 #include "base/memory/scoped_refptr.h"
31 #include "base/optional.h"
32 #include "third_party/blink/public/common/input/web_input_event.h"
33 #include "third_party/blink/public/common/input/web_menu_source_type.h"
34 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
35 #include "third_party/blink/public/platform/web_input_event_result.h"
36 #include "third_party/blink/renderer/core/core_export.h"
37 #include "third_party/blink/renderer/core/events/text_event_input_type.h"
38 #include "third_party/blink/renderer/core/input/fallback_cursor_event_manager.h"
39 #include "third_party/blink/renderer/core/input/gesture_manager.h"
40 #include "third_party/blink/renderer/core/input/keyboard_event_manager.h"
41 #include "third_party/blink/renderer/core/input/mouse_event_manager.h"
42 #include "third_party/blink/renderer/core/input/mouse_wheel_event_manager.h"
43 #include "third_party/blink/renderer/core/input/pointer_event_manager.h"
44 #include "third_party/blink/renderer/core/input/scroll_manager.h"
45 #include "third_party/blink/renderer/core/layout/hit_test_request.h"
46 #include "third_party/blink/renderer/core/page/drag_actions.h"
47 #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
48 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
49 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
50 #include "third_party/blink/renderer/platform/geometry/layout_point.h"
51 #include "third_party/blink/renderer/platform/heap/handle.h"
52 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
53 #include "third_party/blink/renderer/platform/wtf/forward.h"
54 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
55 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
56 #include "ui/base/cursor/cursor.h"
57 
58 namespace blink {
59 
60 class DataTransfer;
61 class PaintLayer;
62 class Element;
63 class Event;
64 template <typename EventType>
65 class EventWithHitTestResults;
66 class HTMLFrameSetElement;
67 class HitTestRequest;
68 class HitTestResult;
69 class LayoutObject;
70 class LocalFrame;
71 class Node;
72 class ScrollableArea;
73 class Scrollbar;
74 class SelectionController;
75 class TextEvent;
76 class WebGestureEvent;
77 class WebMouseEvent;
78 class WebMouseWheelEvent;
79 
80 // Handles events for Pointers (Mouse/Touch), HitTests, DragAndDrop, etc.
81 class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
82  public:
83   explicit EventHandler(LocalFrame&);
84   void Trace(Visitor*);
85 
86   void Clear();
87 
88   void UpdateSelectionForMouseDrag();
89   void StartMiddleClickAutoscroll(LayoutObject*);
90 
91   // TODO(nzolghadr): Some of the APIs in this class only forward the action
92   // to the corresponding Manager class. We need to investigate whether it is
93   // better to expose the manager instance itself later or can the access to
94   // those APIs be more limited or removed.
95 
96   void StopAutoscroll();
97 
98   HitTestResult HitTestResultAtLocation(
99       const HitTestLocation&,
100       HitTestRequest::HitTestRequestType hit_type =
101           HitTestRequest::kReadOnly | HitTestRequest::kActive |
102           HitTestRequest::kRetargetForInert,
103       const LayoutObject* stop_node = nullptr,
104       bool no_lifecycle_update = false);
105 
MousePressed()106   bool MousePressed() const { return mouse_event_manager_->MousePressed(); }
IsMousePositionUnknown()107   bool IsMousePositionUnknown() const {
108     return mouse_event_manager_->IsMousePositionUnknown();
109   }
ClearMouseEventManager()110   void ClearMouseEventManager() const { mouse_event_manager_->Clear(); }
111 
112   WebInputEventResult UpdateDragAndDrop(const WebMouseEvent&, DataTransfer*);
113   void CancelDragAndDrop(const WebMouseEvent&, DataTransfer*);
114   WebInputEventResult PerformDragAndDrop(const WebMouseEvent&, DataTransfer*);
115   void UpdateDragStateAfterEditDragIfNeeded(Element* root_editable_element);
116 
117   void ScheduleHoverStateUpdate();
118   void ScheduleCursorUpdate();
119 
120   // Return whether a mouse cursor update is currently pending.  Used for
121   // testing.
122   bool CursorUpdatePending();
123 
124   void SetResizingFrameSet(HTMLFrameSetElement*);
125 
126   void ResizeScrollableAreaDestroyed();
127 
128   FloatPoint LastKnownMousePositionInRootFrame() const;
129   FloatPoint LastKnownMouseScreenPosition() const;
130 
131   IntPoint DragDataTransferLocationForTesting();
132 
133   // Performs a logical scroll that chains, crossing frames, starting from
134   // the given node or a reasonable default (focus/last clicked).
135   bool BubblingScroll(mojom::blink::ScrollDirection,
136                       ScrollGranularity,
137                       Node* starting_node = nullptr);
138 
139   WebInputEventResult HandleMouseMoveEvent(
140       const WebMouseEvent&,
141       const Vector<WebMouseEvent>& coalesced_events,
142       const Vector<WebMouseEvent>& predicted_events);
143   void HandleMouseLeaveEvent(const WebMouseEvent&);
144 
145   WebInputEventResult HandlePointerEvent(
146       const WebPointerEvent&,
147       const Vector<WebPointerEvent>& coalesced_events,
148       const Vector<WebPointerEvent>& predicted_events);
149 
150   WebInputEventResult DispatchBufferedTouchEvents();
151 
152   WebInputEventResult HandleMousePressEvent(const WebMouseEvent&);
153   WebInputEventResult HandleMouseReleaseEvent(const WebMouseEvent&);
154   WebInputEventResult HandleWheelEvent(const WebMouseWheelEvent&);
155 
156   WebInputEventResult HandleTargetedMouseEvent(
157       Element* target,
158       const WebMouseEvent&,
159       const AtomicString& event_type,
160       const Vector<WebMouseEvent>& coalesced_events,
161       const Vector<WebMouseEvent>& predicted_events,
162       const String& canvas_node_id = String());
163 
164   // Called on the local root frame exactly once per gesture event.
165   WebInputEventResult HandleGestureEvent(const WebGestureEvent&);
166   WebInputEventResult HandleGestureEvent(const GestureEventWithHitTestResults&);
167 
168   // Clear the old hover/active state within frames before moving the hover
169   // state to the another frame. |is_active| specifies whether the active state
170   // is being applied to or removed from the given element. This method should
171   // be initially called on the root document, it will recurse into child
172   // frames as needed.
173   void UpdateCrossFrameHoverActiveState(bool is_active, Element*);
174 
175   // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment
176   // and updating hover/active state across all frames if necessary. This should
177   // be called at most once per gesture event, and called on the local root
178   // frame.
179   // Note: This is similar to (the less clearly named) prepareMouseEvent.
180   // FIXME: Remove readOnly param when there is only ever a single call to this.
181   GestureEventWithHitTestResults TargetGestureEvent(const WebGestureEvent&,
182                                                     bool read_only = false);
183   GestureEventWithHitTestResults HitTestResultForGestureEvent(
184       const WebGestureEvent&,
185       HitTestRequest::HitTestRequestType);
186   // Handle the provided non-scroll gesture event. Should be called only on the
187   // inner frame.
188   WebInputEventResult HandleGestureEventInFrame(
189       const GestureEventWithHitTestResults&);
190 
191   // Handle the provided scroll gesture event, propagating down to child frames
192   // as necessary.
193   WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&);
194   bool IsScrollbarHandlingGestures() const;
195 
196   bool BestClickableNodeForHitTestResult(const HitTestLocation& location,
197                                          const HitTestResult&,
198                                          IntPoint& target_point,
199                                          Node*& target_node);
200   bool BestContextMenuNodeForHitTestResult(const HitTestLocation& location,
201                                            const HitTestResult&,
202                                            IntPoint& target_point,
203                                            Node*& target_node);
204   void CacheTouchAdjustmentResult(uint32_t, FloatPoint);
205 
206   WebInputEventResult SendContextMenuEvent(
207       const WebMouseEvent&,
208       Element* override_target_element = nullptr);
209   WebInputEventResult ShowNonLocatedContextMenu(
210       Element* override_target_element = nullptr,
211       WebMenuSourceType = kMenuSourceNone);
212 
213   // Returns whether pointerId is active or not
214   bool IsPointerEventActive(PointerId);
215 
216   void SetPointerCapture(PointerId, Element*);
217   void ReleasePointerCapture(PointerId, Element*);
218   void ReleaseMousePointerCapture();
219   bool HasPointerCapture(PointerId, const Element*) const;
220 
221   void ElementRemoved(Element*);
222 
223   void SetMouseDownMayStartAutoscroll();
224 
225   bool HandleAccessKey(const WebKeyboardEvent&);
226   WebInputEventResult KeyEvent(const WebKeyboardEvent&);
227   void DefaultKeyboardEventHandler(KeyboardEvent*);
228   bool HandleFallbackCursorModeBackEvent();
229 
230   bool HandleTextInputEvent(const String& text,
231                             Event* underlying_event = nullptr,
232                             TextEventInputType = kTextEventInputKeyboard);
233   void DefaultTextInputEventHandler(TextEvent*);
234 
235   void DragSourceEndedAt(const WebMouseEvent&, DragOperation);
236 
237   void CapsLockStateMayHaveChanged();  // Only called by FrameSelection
238 
239   bool UseHandCursor(Node*, bool is_over_link);
240 
241   void NotifyElementActivated();
242 
GetSelectionController()243   SelectionController& GetSelectionController() const {
244     return *selection_controller_;
245   }
246 
247   bool IsPointerIdActiveOnFrame(PointerId, LocalFrame*) const;
248 
249   LocalFrame* DetermineActivePointerTrackerFrame(PointerId pointer_id) const;
250 
251   // Clears drag target and related states. It is called when drag is done or
252   // canceled.
253   void ClearDragState();
254 
GetEventHandlerRegistry()255   EventHandlerRegistry& GetEventHandlerRegistry() const {
256     return *event_handler_registry_;
257   }
258 
259   void AnimateSnapFling(base::TimeTicks monotonic_time);
260 
261   void RecomputeMouseHoverStateIfNeeded();
262 
263   void MarkHoverStateDirty();
264 
265   void SetIsFallbackCursorModeOn(bool is_on);
266 
267   // Reset the last mouse position so that movement after unlock will be
268   // restart from the lock position.
269   void ResetMousePositionForPointerUnlock();
270 
271   bool LongTapShouldInvokeContextMenu();
272 
273  private:
274   WebInputEventResult HandleMouseMoveOrLeaveEvent(
275       const WebMouseEvent&,
276       const Vector<WebMouseEvent>& coalesced_events,
277       const Vector<WebMouseEvent>& predicted_events,
278       HitTestResult* hovered_node = nullptr,
279       HitTestLocation* hit_test_location = nullptr);
280 
281   // Updates the event, location and result to the adjusted target.
282   void ApplyTouchAdjustment(WebGestureEvent*, HitTestLocation&, HitTestResult*);
283 
284   void PerformHitTest(const HitTestLocation& location,
285                       HitTestResult&,
286                       bool no_lifecycle_update) const;
287 
288   void UpdateGestureTargetNodeForMouseEvent(
289       const GestureEventWithHitTestResults&);
290 
291   bool ShouldApplyTouchAdjustment(const WebGestureEvent&) const;
292   bool GestureCorrespondsToAdjustedTouch(const WebGestureEvent&);
293   bool IsSelectingLink(const HitTestResult&);
294   bool ShouldShowIBeamForNode(const Node*, const HitTestResult&);
295   bool ShouldShowResizeForNode(const Node*, const HitTestLocation&);
296   base::Optional<ui::Cursor> SelectCursor(const HitTestLocation& location,
297                                           const HitTestResult&);
298   base::Optional<ui::Cursor> SelectAutoCursor(const HitTestResult&,
299                                               Node*,
300                                               const ui::Cursor& i_beam);
301 
302   void HoverTimerFired(TimerBase*);
303   void CursorUpdateTimerFired(TimerBase*);
304   void ActiveIntervalTimerFired(TimerBase*);
305 
306   void UpdateCursor();
307 
308   ScrollableArea* AssociatedScrollableArea(const PaintLayer*) const;
309 
310   Element* EffectiveMouseEventTargetElement(Element*);
311 
312   // Dispatches ME after corresponding PE provided the PE has not been
313   // canceled. The |mouse_event_type| arg must be one of {mousedown,
314   // mousemove, mouseup}.
315   WebInputEventResult DispatchMousePointerEvent(
316       const WebInputEvent::Type,
317       Element* target,
318       const String& canvas_region_id,
319       const WebMouseEvent&,
320       const Vector<WebMouseEvent>& coalesced_events,
321       const Vector<WebMouseEvent>& predicted_events,
322       bool skip_click_dispatch = false);
323 
324   WebInputEventResult PassMousePressEventToSubframe(
325       MouseEventWithHitTestResults&,
326       LocalFrame* subframe);
327   WebInputEventResult PassMouseMoveEventToSubframe(
328       MouseEventWithHitTestResults&,
329       const Vector<WebMouseEvent>& coalesced_events,
330       const Vector<WebMouseEvent>& predicted_events,
331       LocalFrame* subframe,
332       HitTestResult* hovered_node = nullptr,
333       HitTestLocation* hit_test_location = nullptr);
334   WebInputEventResult PassMouseReleaseEventToSubframe(
335       MouseEventWithHitTestResults&,
336       LocalFrame* subframe);
337 
338   bool PassMousePressEventToScrollbar(MouseEventWithHitTestResults&);
339 
340   void DefaultSpaceEventHandler(KeyboardEvent*);
341   void DefaultBackspaceEventHandler(KeyboardEvent*);
342   void DefaultTabEventHandler(KeyboardEvent*);
343   void DefaultEscapeEventHandler(KeyboardEvent*);
344   void DefaultArrowEventHandler(mojom::blink::FocusType, KeyboardEvent*);
345 
346   // |last_scrollbar_under_mouse_| is set when the mouse moves off of a
347   // scrollbar, and used to notify it of MouseUp events to release mouse
348   // capture.
349   void UpdateLastScrollbarUnderMouse(Scrollbar*, bool);
350 
351   WebInputEventResult HandleGestureShowPress();
352 
353   bool ShouldBrowserControlsConsumeScroll(FloatSize) const;
354 
355   bool RootFrameTrackedActivePointerInCurrentFrame(PointerId pointer_id) const;
356 
357   void CaptureMouseEventsToWidget(bool);
358 
359   void ReleaseMouseCaptureFromLocalRoot();
360   void ReleaseMouseCaptureFromCurrentFrame();
361 
362   MouseEventWithHitTestResults GetMouseEventTarget(
363       const HitTestRequest& request,
364       const WebMouseEvent& mev);
365 
366   // NOTE: If adding a new field to this class please ensure that it is
367   // cleared in |EventHandler::clear()|.
368 
369   const Member<LocalFrame> frame_;
370 
371   const Member<SelectionController> selection_controller_;
372 
373   // TODO(lanwei): Remove the below timers for updating hover and cursor.
374   TaskRunnerTimer<EventHandler> hover_timer_;
375 
376   // TODO(rbyers): Mouse cursor update is page-wide, not per-frame.  Page-wide
377   // state should move out of EventHandler to a new PageEventHandler class.
378   // crbug.com/449649
379   TaskRunnerTimer<EventHandler> cursor_update_timer_;
380 
381   Member<Element> capturing_mouse_events_element_;
382   // |capturing_subframe_element_| has similar functionality as
383   // |capturing_mouse_events_element_|. It replaces |capturing_..| when
384   // UnifiedPointerCapture enabled.
385   Member<Element> capturing_subframe_element_;
386 
387   // Indicates whether the current widget is capturing mouse input.
388   // Only used for local frame root EventHandlers.
389   bool is_widget_capturing_mouse_events_ = false;
390 
391   Member<LocalFrame> last_mouse_move_event_subframe_;
392   Member<Scrollbar> last_scrollbar_under_mouse_;
393 
394   Member<Node> drag_target_;
395   bool should_only_fire_drag_over_event_;
396 
397   Member<HTMLFrameSetElement> frame_set_being_resized_;
398 
399   // Local frames in the same local root share the same EventHandlerRegistry.
400   Member<EventHandlerRegistry> event_handler_registry_;
401   Member<ScrollManager> scroll_manager_;
402   Member<MouseEventManager> mouse_event_manager_;
403   Member<MouseWheelEventManager> mouse_wheel_event_manager_;
404   Member<KeyboardEventManager> keyboard_event_manager_;
405   Member<PointerEventManager> pointer_event_manager_;
406   Member<GestureManager> gesture_manager_;
407   Member<FallbackCursorEventManager> fallback_cursor_event_manager_;
408 
409   double max_mouse_moved_duration_;
410 
411   TaskRunnerTimer<EventHandler> active_interval_timer_;
412 
413   // last_show_press_timestamp_ prevents the active state rewrited by
414   // following events too soon (less than 0.15s). It is ok we only record
415   // last_show_press_timestamp_ in root frame since root frame will have
416   // subframe as active element if subframe has active element.
417   base::Optional<base::TimeTicks> last_show_press_timestamp_;
418   Member<Element> last_deferred_tap_element_;
419 
420   // Set on GestureTapDown if unique_touch_event_id_ matches cached adjusted
421   // touchstart event id.
422   bool should_use_touch_event_adjusted_point_;
423 
424   // Stored the last touch type primary pointer down adjustment result.
425   // This is used in gesture event hit test.
426   TouchAdjustmentResult touch_adjustment_result_;
427 
428   // ShouldShowIBeamForNode's unit tests:
429   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, HitOnNothingDoesNotShowIBeam);
430   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, HitOnTextShowsIBeam);
431   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
432                            HitOnUserSelectNoneDoesNotShowIBeam);
433   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
434                            ShadowChildCanOverrideUserSelectNone);
435   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
436                            UserSelectAllCanOverrideUserSelectNone);
437   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
438                            UserSelectNoneCanOverrideUserSelectAll);
439   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
440                            UserSelectTextCanOverrideUserSelectNone);
441   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
442                            UserSelectNoneCanOverrideUserSelectText);
443   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
444                            ShadowChildCanOverrideUserSelectText);
445   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, InputFieldsCanStartSelection);
446   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, ImagesCannotStartSelection);
447   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, AnchorTextCannotStartSelection);
448   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
449                            EditableAnchorTextCanStartSelection);
450   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
451                            ReadOnlyInputDoesNotInheritUserSelect);
452   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
453                            CursorForVerticalResizableTextArea);
454   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
455                            CursorForHorizontalResizableTextArea);
456   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForResizableTextArea);
457   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForRtlResizableTextArea);
458   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
459                            CursorForInlineVerticalWritingMode);
460   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForBlockVerticalWritingMode);
461 
462   FRIEND_TEST_ALL_PREFIXES(FallbackCursorEventManagerTest,
463                            MouseMoveCursorLockOnDiv);
464   FRIEND_TEST_ALL_PREFIXES(FallbackCursorEventManagerTest,
465                            MouseMoveCursorLockOnIFrame);
466   FRIEND_TEST_ALL_PREFIXES(FallbackCursorEventManagerTest, KeyBackAndMouseMove);
467   FRIEND_TEST_ALL_PREFIXES(FallbackCursorEventManagerTest, MouseDownOnEditor);
468 
469   DISALLOW_COPY_AND_ASSIGN(EventHandler);
470 };
471 
472 }  // namespace blink
473 
474 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLER_H_
475