80468466b287d0561036a626f1b28f379014fbb4
[platform/framework/web/chromium-efl.git] / third_party / blink / renderer / core / input / event_handler.h
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/gtest_prod_util.h"
30 #include "base/time/time.h"
31 #include "third_party/abseil-cpp/absl/types/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/platform/web_input_event_result.h"
35 #include "third_party/blink/renderer/core/core_export.h"
36 #include "third_party/blink/renderer/core/events/text_event_input_type.h"
37 #include "third_party/blink/renderer/core/input/gesture_manager.h"
38 #include "third_party/blink/renderer/core/input/keyboard_event_manager.h"
39 #include "third_party/blink/renderer/core/input/mouse_event_manager.h"
40 #include "third_party/blink/renderer/core/input/mouse_wheel_event_manager.h"
41 #include "third_party/blink/renderer/core/input/pointer_event_manager.h"
42 #include "third_party/blink/renderer/core/input/scroll_manager.h"
43 #include "third_party/blink/renderer/core/layout/hit_test_request.h"
44 #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
45 #include "third_party/blink/renderer/core/page/touch_adjustment.h"
46 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
47
48 namespace ui {
49 class Cursor;
50 }
51
52 namespace blink {
53
54 class DataTransfer;
55 class PaintLayer;
56 class Element;
57 class Event;
58 class EventHandlerRegistry;
59 template <typename EventType>
60 class EventWithHitTestResults;
61 class HTMLFrameSetElement;
62 class HitTestRequest;
63 class HitTestResult;
64 class LayoutObject;
65 class LocalFrame;
66 class Node;
67 class ScrollableArea;
68 class Scrollbar;
69 class SelectionController;
70 class TextEvent;
71 class WebGestureEvent;
72 class WebMouseEvent;
73 class WebMouseWheelEvent;
74
75 // Handles events for Pointers (Mouse/Touch), HitTests, DragAndDrop, etc.
76 class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
77  public:
78   explicit EventHandler(LocalFrame&);
79   EventHandler(const EventHandler&) = delete;
80   EventHandler& operator=(const EventHandler&) = delete;
81   void Trace(Visitor*) const;
82
83   void Clear();
84
85   void UpdateSelectionForMouseDrag();
86   void StartMiddleClickAutoscroll(LayoutObject*);
87
88   // TODO(nzolghadr): Some of the APIs in this class only forward the action
89   // to the corresponding Manager class. We need to investigate whether it is
90   // better to expose the manager instance itself later or can the access to
91   // those APIs be more limited or removed.
92
93   void StopAutoscroll();
94
95   HitTestResult HitTestResultAtLocation(
96       const HitTestLocation&,
97       HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kReadOnly |
98                                                     HitTestRequest::kActive,
99       const LayoutObject* stop_node = nullptr,
100       bool no_lifecycle_update = false);
101
102   bool MousePressed() const { return mouse_event_manager_->MousePressed(); }
103   bool IsMousePositionUnknown() const {
104     return mouse_event_manager_->IsMousePositionUnknown();
105   }
106   void ClearMouseEventManager() const { mouse_event_manager_->Clear(); }
107
108   WebInputEventResult UpdateDragAndDrop(const WebMouseEvent&, DataTransfer*);
109   void CancelDragAndDrop(const WebMouseEvent&, DataTransfer*);
110   WebInputEventResult PerformDragAndDrop(const WebMouseEvent&, DataTransfer*);
111   void UpdateDragStateAfterEditDragIfNeeded(Element* root_editable_element);
112
113   void ScheduleHoverStateUpdate();
114   void ScheduleCursorUpdate();
115
116   // Return whether a mouse cursor update is currently pending.  Used for
117   // testing.
118   bool CursorUpdatePending();
119
120   bool IsHandlingKeyEvent() const;
121
122   void SetResizingFrameSet(HTMLFrameSetElement*);
123
124   void ResizeScrollableAreaDestroyed();
125
126   gfx::PointF LastKnownMousePositionInRootFrame() const;
127   gfx::PointF LastKnownMouseScreenPosition() const;
128
129   gfx::Point DragDataTransferLocationForTesting();
130
131   // Performs a logical scroll that chains, crossing frames, starting from
132   // the given node or a reasonable default (focus/last clicked).
133   bool BubblingScroll(mojom::blink::ScrollDirection,
134                       ui::ScrollGranularity,
135                       Node* starting_node = nullptr);
136
137   WebInputEventResult HandleMouseMoveEvent(
138       const WebMouseEvent&,
139       const Vector<WebMouseEvent>& coalesced_events,
140       const Vector<WebMouseEvent>& predicted_events);
141   void HandleMouseLeaveEvent(const WebMouseEvent&);
142
143   WebInputEventResult HandlePointerEvent(
144       const WebPointerEvent&,
145       const Vector<WebPointerEvent>& coalesced_events,
146       const Vector<WebPointerEvent>& predicted_events);
147
148   WebInputEventResult DispatchBufferedTouchEvents();
149
150   WebInputEventResult HandleMousePressEvent(const WebMouseEvent&);
151   WebInputEventResult HandleMouseReleaseEvent(const WebMouseEvent&);
152   WebInputEventResult HandleWheelEvent(const WebMouseWheelEvent&);
153
154   WebInputEventResult HandleTargetedMouseEvent(
155       Element* target,
156       const WebMouseEvent&,
157       const AtomicString& event_type,
158       const Vector<WebMouseEvent>& coalesced_events,
159       const Vector<WebMouseEvent>& predicted_events);
160
161   // Called on the local root frame exactly once per gesture event.
162   WebInputEventResult HandleGestureEvent(const WebGestureEvent&);
163   WebInputEventResult HandleGestureEvent(const GestureEventWithHitTestResults&);
164
165   // Clear the old hover/active state within frames before moving the hover
166   // state to the another frame. |is_active| specifies whether the active state
167   // is being applied to or removed from the given element. This method should
168   // be initially called on the root document, it will recurse into child
169   // frames as needed.
170   void UpdateCrossFrameHoverActiveState(bool is_active, Element*);
171
172   // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment
173   // and updating hover/active state across all frames if necessary. This should
174   // be called at most once per gesture event, and called on the local root
175   // frame.
176   // Note: This is similar to (the less clearly named) prepareMouseEvent.
177   // FIXME: Remove readOnly param when there is only ever a single call to this.
178   GestureEventWithHitTestResults TargetGestureEvent(const WebGestureEvent&,
179                                                     bool read_only = false);
180   GestureEventWithHitTestResults HitTestResultForGestureEvent(
181       const WebGestureEvent&,
182       HitTestRequest::HitTestRequestType);
183
184   // Handle the provided scroll gesture event, propagating down to child frames
185   // as necessary.
186   WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&);
187   bool IsScrollbarHandlingGestures() const;
188
189   bool BestNodeForHitTestResult(TouchAdjustmentCandidateType candidate_type,
190                                 const HitTestLocation& location,
191                                 const HitTestResult&,
192                                 gfx::Point& adjusted_point,
193                                 Node*& adjusted_node);
194   void CacheTouchAdjustmentResult(uint32_t, gfx::PointF);
195
196   // Dispatch a context menu event. If |override_target_element| is provided,
197   // the context menu event will use that, so that the browser-generated context
198   // menu will be filled with options relevant to it, rather than the element
199   // found via hit testing the event's screen point. This is used so that a
200   // context menu generated via the keyboard reliably uses the correct target.
201   WebInputEventResult SendContextMenuEvent(
202       const WebMouseEvent&,
203       Element* override_target_element = nullptr);
204   WebInputEventResult ShowNonLocatedContextMenu(
205       Element* override_target_element = nullptr,
206       WebMenuSourceType = kMenuSourceNone);
207
208   // Returns whether pointerId is active or not
209   bool IsPointerEventActive(PointerId);
210
211   void SetPointerCapture(PointerId, Element*, bool explicit_capture = false);
212   void ReleasePointerCapture(PointerId, Element*);
213   void ReleaseMousePointerCapture();
214   bool HasPointerCapture(PointerId, const Element*) const;
215
216   void ElementRemoved(Element*);
217
218   void SetMouseDownMayStartAutoscroll();
219
220   bool HandleAccessKey(const WebKeyboardEvent&);
221   WebInputEventResult KeyEvent(const WebKeyboardEvent&);
222   void DefaultKeyboardEventHandler(KeyboardEvent*);
223
224   bool HandleTextInputEvent(const String& text,
225                             Event* underlying_event = nullptr,
226                             TextEventInputType = kTextEventInputKeyboard);
227   void DefaultTextInputEventHandler(TextEvent*);
228
229   void DragSourceEndedAt(const WebMouseEvent&, ui::mojom::blink::DragOperation);
230
231   void CapsLockStateMayHaveChanged();  // Only called by FrameSelection
232
233   static bool UsesHandCursor(const Node*);
234
235   void NotifyElementActivated();
236
237   SelectionController& GetSelectionController() const {
238     return *selection_controller_;
239   }
240
241   bool IsPointerIdActiveOnFrame(PointerId, LocalFrame*) const;
242
243   LocalFrame* DetermineActivePointerTrackerFrame(PointerId pointer_id) const;
244 #if BUILDFLAG(IS_EFL)
245   void ContextMenuEventForWordOrLinkSelection(const WebGestureEvent&);
246 #endif
247
248 #if BUILDFLAG(IS_TIZEN)
249   void EnterDragState();
250 #endif
251
252   // Clears drag target and related states. It is called when drag is done or
253   // canceled.
254   void ClearDragState();
255
256 #if BUILDFLAG(IS_TIZEN_TV)
257   bool ScrollNewPosition(const ScrollOffset&, LocalFrameView*);
258   bool ScrollWithMultiplier(const ScrollOffset&, Node*);
259 #endif
260
261   EventHandlerRegistry& GetEventHandlerRegistry() const {
262     return *event_handler_registry_;
263   }
264
265   GestureManager& GetGestureManager() const { return *gesture_manager_; }
266
267   KeyboardEventManager& GetKeyboardEventManager() const {
268     return *keyboard_event_manager_;
269   }
270
271   void RecomputeMouseHoverStateIfNeeded();
272
273   void MarkHoverStateDirty();
274
275   // Reset the last mouse position so that movement after unlock will be
276   // restart from the lock position.
277   void ResetMousePositionForPointerUnlock();
278
279   bool LongTapShouldInvokeContextMenu();
280
281   void UpdateCursor();
282
283   float cursor_accessibility_scale_factor() const {
284     return cursor_accessibility_scale_factor_;
285   }
286   void set_cursor_accessibility_scale_factor(float scale) {
287     cursor_accessibility_scale_factor_ = scale;
288   }
289
290   Element* GetElementUnderMouse();
291
292   Element* CurrentTouchDownElement();
293
294   void SetDelayedNavigationTaskHandle(TaskHandle task_handle);
295
296   TaskHandle& GetDelayedNavigationTaskHandle();
297
298  private:
299   WebInputEventResult HandleMouseMoveOrLeaveEvent(
300       const WebMouseEvent&,
301       const Vector<WebMouseEvent>& coalesced_events,
302       const Vector<WebMouseEvent>& predicted_events,
303       HitTestResult* hovered_node = nullptr,
304       HitTestLocation* hit_test_location = nullptr);
305
306   // Updates the event, location and result to the adjusted target.
307   void ApplyTouchAdjustment(WebGestureEvent*, HitTestLocation&, HitTestResult&);
308
309   void PerformHitTest(const HitTestLocation& location,
310                       HitTestResult&,
311                       bool no_lifecycle_update) const;
312
313   void UpdateGestureTargetNodeForMouseEvent(
314       const GestureEventWithHitTestResults&);
315
316   // Handle the provided non-scroll gesture event. Should be called only on the
317   // inner frame.
318   WebInputEventResult HandleGestureEventInFrame(
319       const GestureEventWithHitTestResults&);
320
321   bool ShouldApplyTouchAdjustment(const WebGestureEvent&) const;
322   bool GestureCorrespondsToAdjustedTouch(const WebGestureEvent&);
323   bool IsSelectingLink(const HitTestResult&);
324   bool ShouldShowIBeamForNode(const Node*, const HitTestResult&);
325   bool ShouldShowResizeForNode(const LayoutObject&, const HitTestLocation&);
326   absl::optional<ui::Cursor> SelectCursor(const HitTestLocation& location,
327                                           const HitTestResult&);
328   absl::optional<ui::Cursor> SelectAutoCursor(const HitTestResult&,
329                                               Node*,
330                                               const ui::Cursor& i_beam);
331
332 #if BUILDFLAG(IS_TIZEN_TV)
333   bool CanRunArrowScrolling(const HitTestResult&);
334 #endif
335
336   void HoverTimerFired(TimerBase*);
337   void CursorUpdateTimerFired(TimerBase*);
338   void ActiveIntervalTimerFired(TimerBase*);
339
340   ScrollableArea* AssociatedScrollableArea(const PaintLayer*) const;
341
342   Element* EffectiveMouseEventTargetElement(Element*);
343
344   // Task handle used to distinguish single/double click with some modifiers.
345   //
346   // When single click with some modifiers occurred, this task handle is set.
347   // If double click follows, this is cancelled and renderer emit double click
348   // event. (By default, it is handled by renderer as text selection.) If not,
349   // the delayed navigation is emitted.
350   //
351   // Currently, the target navigations are the followings:
352   //
353   // - Download (Alt-click with/without some other modifiers.)
354   // - Link Preview (Alt-click)
355   //
356   // For more details, see https://crbug.com/1428816.
357   TaskHandle delayed_navigation_task_handle_;
358
359   // Dispatches ME after corresponding PE provided the PE has not been
360   // canceled. The |mouse_event_type| arg must be one of {mousedown,
361   // mousemove, mouseup}.
362   WebInputEventResult DispatchMousePointerEvent(
363       const WebInputEvent::Type,
364       Element* target,
365       const WebMouseEvent&,
366       const Vector<WebMouseEvent>& coalesced_events,
367       const Vector<WebMouseEvent>& predicted_events,
368       bool skip_click_dispatch = false);
369
370   WebInputEventResult PassMousePressEventToSubframe(
371       MouseEventWithHitTestResults&,
372       LocalFrame* subframe);
373   WebInputEventResult PassMouseMoveEventToSubframe(
374       MouseEventWithHitTestResults&,
375       const Vector<WebMouseEvent>& coalesced_events,
376       const Vector<WebMouseEvent>& predicted_events,
377       LocalFrame* subframe,
378       HitTestResult* hovered_node = nullptr,
379       HitTestLocation* hit_test_location = nullptr);
380   WebInputEventResult PassMouseReleaseEventToSubframe(
381       MouseEventWithHitTestResults&,
382       LocalFrame* subframe);
383
384   bool PassMousePressEventToScrollbar(MouseEventWithHitTestResults&);
385
386   // |last_scrollbar_under_mouse_| is set when the mouse moves off of a
387   // scrollbar, and used to notify it of MouseUp events to release mouse
388   // capture.
389   void UpdateLastScrollbarUnderMouse(Scrollbar*, bool);
390
391   WebInputEventResult HandleGestureShowPress();
392
393   bool RootFrameTrackedActivePointerInCurrentFrame(PointerId pointer_id) const;
394
395   void CaptureMouseEventsToWidget(bool);
396
397   void ReleaseMouseCaptureFromLocalRoot();
398   void ReleaseMouseCaptureFromCurrentFrame();
399
400   MouseEventWithHitTestResults GetMouseEventTarget(
401       const HitTestRequest& request,
402       const WebMouseEvent& mev);
403
404   // Returned rect is in local root frame coordinates.
405   gfx::Rect GetFocusedElementRectForNonLocatedContextMenu(
406       Element* focused_element);
407
408   // NOTE: If adding a new field to this class please ensure that it is
409   // cleared in |EventHandler::clear()|.
410
411   const Member<LocalFrame> frame_;
412
413   const Member<SelectionController> selection_controller_;
414
415   // TODO(lanwei): Remove the below timers for updating hover and cursor.
416   HeapTaskRunnerTimer<EventHandler> hover_timer_;
417
418   // TODO(rbyers): Mouse cursor update is page-wide, not per-frame.  Page-wide
419   // state should move out of EventHandler to a new PageEventHandler class.
420   // crbug.com/449649
421   HeapTaskRunnerTimer<EventHandler> cursor_update_timer_;
422
423   Member<Element> capturing_mouse_events_element_;
424   // |capturing_subframe_element_| has similar functionality as
425   // |capturing_mouse_events_element_|. It replaces |capturing_..| when
426   // UnifiedPointerCapture enabled.
427   Member<Element> capturing_subframe_element_;
428
429   // Indicates whether the current widget is capturing mouse input.
430   // Only used for local frame root EventHandlers.
431   bool is_widget_capturing_mouse_events_ = false;
432
433   Member<LocalFrame> last_mouse_move_event_subframe_;
434   Member<Scrollbar> last_scrollbar_under_mouse_;
435
436   Member<Node> drag_target_;
437   bool should_only_fire_drag_over_event_;
438
439   Member<HTMLFrameSetElement> frame_set_being_resized_;
440
441   // Local frames in the same local root share the same EventHandlerRegistry.
442   Member<EventHandlerRegistry> event_handler_registry_;
443   Member<ScrollManager> scroll_manager_;
444   Member<MouseEventManager> mouse_event_manager_;
445   Member<MouseWheelEventManager> mouse_wheel_event_manager_;
446   Member<KeyboardEventManager> keyboard_event_manager_;
447   Member<PointerEventManager> pointer_event_manager_;
448   Member<GestureManager> gesture_manager_;
449
450   double max_mouse_moved_duration_;
451
452   float cursor_accessibility_scale_factor_ = 1.f;
453
454   HeapTaskRunnerTimer<EventHandler> active_interval_timer_;
455
456   // last_show_press_timestamp_ prevents the active state rewrited by
457   // following events too soon (less than 0.15s). It is ok we only record
458   // last_show_press_timestamp_ in root frame since root frame will have
459   // subframe as active element if subframe has active element.
460   absl::optional<base::TimeTicks> last_show_press_timestamp_;
461   Member<Element> last_deferred_tap_element_;
462
463   // Set on GestureTapDown if unique_touch_event_id_ matches cached adjusted
464   // touchstart event id.
465   bool should_use_touch_event_adjusted_point_;
466
467   // Stored the last touch type primary pointer down adjustment result.
468   // This is used in gesture event hit test.
469   TouchAdjustmentResult touch_adjustment_result_;
470
471   struct {
472     DOMNodeId mouse_down_target = kInvalidDOMNodeId;
473     DOMNodeId tap_target = kInvalidDOMNodeId;
474     base::TimeTicks mouse_down_time;
475     base::TimeTicks tap_time;
476   } discarded_events_;
477
478 #if BUILDFLAG(IS_TIZEN_TV)
479   bool handled_mouse_left_button_press_event_ = false;
480 #endif
481
482   // ShouldShowIBeamForNode's unit tests:
483   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, HitOnNothingDoesNotShowIBeam);
484   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, HitOnTextShowsIBeam);
485   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
486                            HitOnUserSelectNoneDoesNotShowIBeam);
487   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
488                            ShadowChildCanOverrideUserSelectNone);
489   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
490                            UserSelectAllCanOverrideUserSelectNone);
491   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
492                            UserSelectNoneCanOverrideUserSelectAll);
493   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
494                            UserSelectTextCanOverrideUserSelectNone);
495   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
496                            UserSelectNoneCanOverrideUserSelectText);
497   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
498                            ShadowChildCanOverrideUserSelectText);
499   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, InputFieldsCanStartSelection);
500   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, ImagesCannotStartSelection);
501   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, AnchorTextCannotStartSelection);
502   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
503                            EditableAnchorTextCanStartSelection);
504   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
505                            ReadOnlyInputDoesNotInheritUserSelect);
506   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
507                            CursorForVerticalResizableTextArea);
508   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
509                            CursorForHorizontalResizableTextArea);
510   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForResizableTextArea);
511   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForRtlResizableTextArea);
512   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
513                            CursorForInlineVerticalWritingMode);
514   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest, CursorForBlockVerticalWritingMode);
515 };
516
517 }  // namespace blink
518
519 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLER_H_