Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: third_party/WebKit/Source/core/input/EventHandlingUtil.cpp

Issue 2255323004: Create MouseEventManager and EventHandlingUtil (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/input/EventHandlingUtil.h"
6
7 #include "core/frame/FrameView.h"
8
9 namespace blink {
10 namespace EventHandlingUtil {
11
12 namespace {
13
14 bool isInDocument(EventTarget* n)
15 {
16 return n && n->toNode() && n->toNode()->isConnected();
17 }
18
19 void buildAncestorChain(
20 EventTarget* target,
21 HeapVector<Member<Node>, 20>* ancestors)
22 {
23 if (!isInDocument(target))
24 return;
25 Node* targetNode = target->toNode();
26 DCHECK(targetNode);
27 targetNode->updateDistribution();
28 // Index 0 element in the ancestors arrays will be the corresponding
29 // target. So the root of their document will be their last element.
30 for (Node* node = targetNode; node; node = FlatTreeTraversal::parent(*node))
31 ancestors->append(node);
32 }
33
34 void buildAncestorChainsAndFindCommonAncestors(
35 EventTarget* exitedTarget, EventTarget* enteredTarget,
36 HeapVector<Member<Node>, 20>* exitedAncestorsOut,
37 HeapVector<Member<Node>, 20>* enteredAncestorsOut,
38 size_t* exitedAncestorsCommonParentIndexOut,
39 size_t* enteredAncestorsCommonParentIndexOut)
40 {
41 DCHECK(exitedAncestorsOut);
42 DCHECK(enteredAncestorsOut);
43 DCHECK(exitedAncestorsCommonParentIndexOut);
44 DCHECK(enteredAncestorsCommonParentIndexOut);
45
46 buildAncestorChain(exitedTarget, exitedAncestorsOut);
47 buildAncestorChain(enteredTarget, enteredAncestorsOut);
48
49 *exitedAncestorsCommonParentIndexOut = exitedAncestorsOut->size();
50 *enteredAncestorsCommonParentIndexOut = enteredAncestorsOut->size();
51 while (*exitedAncestorsCommonParentIndexOut > 0
52 && *enteredAncestorsCommonParentIndexOut > 0) {
53 if ((*exitedAncestorsOut)[(*exitedAncestorsCommonParentIndexOut) - 1]
54 != (*enteredAncestorsOut)[(*enteredAncestorsCommonParentIndexOut) - 1])
55 break;
56 (*exitedAncestorsCommonParentIndexOut)--;
57 (*enteredAncestorsCommonParentIndexOut)--;
58 }
59 }
60
61 } // namespace
62
63 HitTestResult hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
64 {
65 HitTestResult result(HitTestRequest(hitType), point);
66
67 if (!frame || frame->contentLayoutItem().isNull())
68 return result;
69 if (frame->view()) {
70 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars);
71 if (!rect.contains(roundedIntPoint(point)))
72 return result;
73 }
74 frame->contentLayoutItem().hitTest(result);
75 return result;
76 }
77
78 WebInputEventResult mergeEventResult(
79 WebInputEventResult resultA, WebInputEventResult resultB)
80 {
81 // The ordering of the enumeration is specific. There are times that
82 // multiple events fire and we need to combine them into a single
83 // result code. The enumeration is based on the level of consumption that
84 // is most significant. The enumeration is ordered with smaller specified
85 // numbers first. Examples of merged results are:
86 // (HandledApplication, HandledSystem) -> HandledSystem
87 // (NotHandled, HandledApplication) -> HandledApplication
88 static_assert(static_cast<int>(WebInputEventResult::NotHandled) == 0, "WebIn putEventResult not ordered");
89 static_assert(static_cast<int>(WebInputEventResult::HandledSuppressed) < sta tic_cast<int>(WebInputEventResult::HandledApplication), "WebInputEventResult not ordered");
90 static_assert(static_cast<int>(WebInputEventResult::HandledApplication) < st atic_cast<int>(WebInputEventResult::HandledSystem), "WebInputEventResult not ord ered");
91 return static_cast<WebInputEventResult>(max(static_cast<int>(resultA), stati c_cast<int>(resultB)));
92 }
93
94 WebInputEventResult toWebInputEventResult(
95 DispatchEventResult result)
96 {
97 switch (result) {
98 case DispatchEventResult::NotCanceled:
99 return WebInputEventResult::NotHandled;
100 case DispatchEventResult::CanceledByEventHandler:
101 return WebInputEventResult::HandledApplication;
102 case DispatchEventResult::CanceledByDefaultEventHandler:
103 return WebInputEventResult::HandledSystem;
104 case DispatchEventResult::CanceledBeforeDispatch:
105 return WebInputEventResult::HandledSuppressed;
106 default:
107 NOTREACHED();
108 return WebInputEventResult::HandledSystem;
109 }
110 }
111
112 void sendBoundaryEvents(
mustaq 2016/08/23 15:20:48 Make it a member function in BoundaryEventDispatch
Navid Zolghadr 2016/08/24 16:07:28 You mean the methods in anonymous name space in th
mustaq 2016/08/26 19:31:44 - The methods in the anonymous namespace have no u
Navid Zolghadr 2016/08/30 18:46:26 I moved the BoundaryEventDispatcher class to anoth
113 EventTarget* exitedTarget,
114 EventTarget* enteredTarget,
115 BoundaryEventDispatcher* dispatcher)
116 {
117 if (exitedTarget == enteredTarget)
118 return;
119
120 // Dispatch out/out events
121 if (isInDocument(exitedTarget))
122 dispatcher->dispatchOut(exitedTarget, enteredTarget);
123
124 // Create lists of all exited/entered ancestors, locate the common ancestor
125 // Based on httparchive, in more than 97% cases the depth of DOM is less
126 // than 20.
127 HeapVector<Member<Node>, 20> exitedAncestors;
128 HeapVector<Member<Node>, 20> enteredAncestors;
129 size_t exitedAncestorsCommonParentIndex = 0;
130 size_t enteredAncestorsCommonParentIndex = 0;
131
132 // A note on mouseenter and mouseleave: These are non-bubbling events, and t hey are dispatched if there
133 // is a capturing event handler on an ancestor or a normal event handler on the element itself. This special
134 // handling is necessary to avoid O(n^2) capturing event handler checks.
135 //
136 // Note, however, that this optimization can possibly cause some unanswere d/missing/redundant mouseenter or
137 // mouseleave events in certain contrived eventhandling scenarios, e.g., whe n:
138 // - the mouseleave handler for a node sets the only capturing-mouseleave-li stener in its ancestor, or
139 // - DOM mods in any mouseenter/mouseleave handler changes the common ancest or of exited & entered nodes, etc.
140 // We think the spec specifies a "frozen" state to avoid such corner cases ( check the discussion on "candidate event
141 // listeners" at http://www.w3.org/TR/uievents), but our code below preserve s one such behavior from past only to
142 // match Firefox and IE behavior.
143 //
144 // TODO(mustaq): Confirm spec conformance, double-check with other browsers.
145
146 buildAncestorChainsAndFindCommonAncestors(
147 exitedTarget, enteredTarget,
148 &exitedAncestors, &enteredAncestors,
149 &exitedAncestorsCommonParentIndex, &enteredAncestorsCommonParentIndex);
150
151 bool exitedNodeHasCapturingAncestor = false;
152 for (size_t j = 0; j < exitedAncestors.size(); j++) {
153 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave)
154 || (RuntimeEnabledFeatures::pointerEventEnabled()
155 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames ::pointerleave)))
156 exitedNodeHasCapturingAncestor = true;
157 }
158
159 // Dispatch leave events, in child-to-parent order.
160 for (size_t j = 0; j < exitedAncestorsCommonParentIndex; j++)
161 dispatcher->dispatchLeave(exitedTarget, enteredTarget, !exitedNodeHasCap turingAncestor);
162
163 // Dispatch over
164 if (isInDocument(enteredTarget))
165 dispatcher->dispatchOver(enteredTarget, exitedTarget);
166
167 // Defer locating capturing enter listener until /after/ dispatching the lea ve events because
168 // the leave handlers might set a capturing enter handler.
169 bool enteredNodeHasCapturingAncestor = false;
170 for (size_t i = 0; i < enteredAncestors.size(); i++) {
171 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter)
172 || (RuntimeEnabledFeatures::pointerEventEnabled()
173 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeName s::pointerenter)))
174 enteredNodeHasCapturingAncestor = true;
175 }
176
177 // Dispatch enter events, in parent-to-child order.
178 for (size_t i = enteredAncestorsCommonParentIndex; i > 0; i--)
179 dispatcher->dispatchEnter(enteredTarget, exitedTarget, !enteredNodeHasCa pturingAncestor);
180 }
181
182 } // namespace EventHandlingUtil
183 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698