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

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

Issue 2255323004: Create MouseEventManager and EventHandlingUtil (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Applying comments Created 4 years, 3 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/BoundaryEventDispatcher.h"
6
7 #include "core/dom/Node.h"
8 #include "core/dom/shadow/FlatTreeTraversal.h"
9
10 namespace blink {
11
12 namespace {
13
14 bool isInDocument(EventTarget* n)
haraken 2016/09/01 17:21:58 n => target
Navid Zolghadr 2016/09/01 19:31:54 Done.
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 void BoundaryEventDispatcher::sendBoundaryEvents(
64 EventTarget* exitedTarget,
65 EventTarget* enteredTarget)
66 {
67 if (exitedTarget == enteredTarget)
68 return;
69
70 // Dispatch out event
71 if (isInDocument(exitedTarget))
72 dispatchOut(exitedTarget, enteredTarget);
73
74 // Create lists of all exited/entered ancestors, locate the common ancestor
75 // Based on httparchive, in more than 97% cases the depth of DOM is less
76 // than 20.
77 HeapVector<Member<Node>, 20> exitedAncestors;
78 HeapVector<Member<Node>, 20> enteredAncestors;
79 size_t exitedAncestorsCommonParentIndex = 0;
80 size_t enteredAncestorsCommonParentIndex = 0;
81
82 // A note on mouseenter and mouseleave: These are non-bubbling events, and t hey are dispatched if there
83 // is a capturing event handler on an ancestor or a normal event handler on the element itself. This special
84 // handling is necessary to avoid O(n^2) capturing event handler checks.
85 //
86 // Note, however, that this optimization can possibly cause some unanswere d/missing/redundant mouseenter or
87 // mouseleave events in certain contrived eventhandling scenarios, e.g., whe n:
88 // - the mouseleave handler for a node sets the only capturing-mouseleave-li stener in its ancestor, or
89 // - DOM mods in any mouseenter/mouseleave handler changes the common ancest or of exited & entered nodes, etc.
90 // We think the spec specifies a "frozen" state to avoid such corner cases ( check the discussion on "candidate event
91 // listeners" at http://www.w3.org/TR/uievents), but our code below preserve s one such behavior from past only to
92 // match Firefox and IE behavior.
93 //
94 // TODO(mustaq): Confirm spec conformance, double-check with other browsers.
95
96 buildAncestorChainsAndFindCommonAncestors(
97 exitedTarget, enteredTarget,
98 &exitedAncestors, &enteredAncestors,
99 &exitedAncestorsCommonParentIndex, &enteredAncestorsCommonParentIndex);
100
101 bool exitedNodeHasCapturingAncestor = false;
102 for (size_t j = 0; j < exitedAncestors.size(); j++) {
103 if (exitedAncestors[j]->hasCapturingEventListeners(getLeaveEvent()))
104 exitedNodeHasCapturingAncestor = true;
105 }
106
107 // Dispatch leave events, in child-to-parent order.
108 for (size_t j = 0; j < exitedAncestorsCommonParentIndex; j++)
109 dispatchLeave(exitedAncestors[j], enteredTarget, !exitedNodeHasCapturing Ancestor);
110
111 // Dispatch over event
112 if (isInDocument(enteredTarget))
113 dispatchOver(enteredTarget, exitedTarget);
114
115 // Defer locating capturing enter listener until /after/ dispatching the lea ve events because
116 // the leave handlers might set a capturing enter handler.
117 bool enteredNodeHasCapturingAncestor = false;
118 for (size_t i = 0; i < enteredAncestors.size(); i++) {
119 if (enteredAncestors[i]->hasCapturingEventListeners(getEnterEvent()))
120 enteredNodeHasCapturingAncestor = true;
121 }
122
123 // Dispatch enter events, in parent-to-child order.
124 for (size_t i = enteredAncestorsCommonParentIndex; i > 0; i--)
125 dispatchEnter(enteredAncestors[i - 1], exitedTarget, !enteredNodeHasCapt uringAncestor);
126 }
127
128 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698