OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/input/BoundaryEventDispatcher.h" | 5 #include "core/input/BoundaryEventDispatcher.h" |
6 | 6 |
7 #include "core/dom/Node.h" | 7 #include "core/dom/Node.h" |
8 #include "core/dom/shadow/FlatTreeTraversal.h" | 8 #include "core/dom/shadow/FlatTreeTraversal.h" |
| 9 #include "core/input/EventHandlingUtil.h" |
9 | 10 |
10 namespace blink { | 11 namespace blink { |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 bool IsInDocument(EventTarget* target) { | |
15 return target && target->ToNode() && target->ToNode()->isConnected(); | |
16 } | |
17 | |
18 void BuildAncestorChain(EventTarget* target, | 15 void BuildAncestorChain(EventTarget* target, |
19 HeapVector<Member<Node>, 20>* ancestors) { | 16 HeapVector<Member<Node>, 20>* ancestors) { |
20 if (!IsInDocument(target)) | 17 if (!EventHandlingUtil::IsInDocument(target)) |
21 return; | 18 return; |
22 Node* target_node = target->ToNode(); | 19 Node* target_node = target->ToNode(); |
23 DCHECK(target_node); | 20 DCHECK(target_node); |
24 target_node->UpdateDistribution(); | 21 target_node->UpdateDistribution(); |
25 // Index 0 element in the ancestors arrays will be the corresponding | 22 // Index 0 element in the ancestors arrays will be the corresponding |
26 // target. So the root of their document will be their last element. | 23 // target. So the root of their document will be their last element. |
27 for (Node* node = target_node; node; node = FlatTreeTraversal::Parent(*node)) | 24 for (Node* node = target_node; node; node = FlatTreeTraversal::Parent(*node)) |
28 ancestors->push_back(node); | 25 ancestors->push_back(node); |
29 } | 26 } |
30 | 27 |
(...skipping 27 matching lines...) Expand all Loading... |
58 } | 55 } |
59 | 56 |
60 } // namespace | 57 } // namespace |
61 | 58 |
62 void BoundaryEventDispatcher::SendBoundaryEvents(EventTarget* exited_target, | 59 void BoundaryEventDispatcher::SendBoundaryEvents(EventTarget* exited_target, |
63 EventTarget* entered_target) { | 60 EventTarget* entered_target) { |
64 if (exited_target == entered_target) | 61 if (exited_target == entered_target) |
65 return; | 62 return; |
66 | 63 |
67 // Dispatch out event | 64 // Dispatch out event |
68 if (IsInDocument(exited_target)) | 65 if (EventHandlingUtil::IsInDocument(exited_target)) |
69 DispatchOut(exited_target, entered_target); | 66 DispatchOut(exited_target, entered_target); |
70 | 67 |
71 // Create lists of all exited/entered ancestors, locate the common ancestor | 68 // Create lists of all exited/entered ancestors, locate the common ancestor |
72 // Based on httparchive, in more than 97% cases the depth of DOM is less | 69 // Based on httparchive, in more than 97% cases the depth of DOM is less |
73 // than 20. | 70 // than 20. |
74 HeapVector<Member<Node>, 20> exited_ancestors; | 71 HeapVector<Member<Node>, 20> exited_ancestors; |
75 HeapVector<Member<Node>, 20> entered_ancestors; | 72 HeapVector<Member<Node>, 20> entered_ancestors; |
76 size_t exited_ancestors_common_parent_index = 0; | 73 size_t exited_ancestors_common_parent_index = 0; |
77 size_t entered_ancestors_common_parent_index = 0; | 74 size_t entered_ancestors_common_parent_index = 0; |
78 | 75 |
(...skipping 29 matching lines...) Expand all Loading... |
108 break; | 105 break; |
109 } | 106 } |
110 } | 107 } |
111 | 108 |
112 // Dispatch leave events, in child-to-parent order. | 109 // Dispatch leave events, in child-to-parent order. |
113 for (size_t j = 0; j < exited_ancestors_common_parent_index; j++) | 110 for (size_t j = 0; j < exited_ancestors_common_parent_index; j++) |
114 DispatchLeave(exited_ancestors[j], entered_target, | 111 DispatchLeave(exited_ancestors[j], entered_target, |
115 !exited_node_has_capturing_ancestor); | 112 !exited_node_has_capturing_ancestor); |
116 | 113 |
117 // Dispatch over event | 114 // Dispatch over event |
118 if (IsInDocument(entered_target)) | 115 if (EventHandlingUtil::IsInDocument(entered_target)) |
119 DispatchOver(entered_target, exited_target); | 116 DispatchOver(entered_target, exited_target); |
120 | 117 |
121 // Defer locating capturing enter listener until /after/ dispatching the leave | 118 // Defer locating capturing enter listener until /after/ dispatching the leave |
122 // events because the leave handlers might set a capturing enter handler. | 119 // events because the leave handlers might set a capturing enter handler. |
123 bool entered_node_has_capturing_ancestor = false; | 120 bool entered_node_has_capturing_ancestor = false; |
124 const AtomicString& enter_event = GetEnterEvent(); | 121 const AtomicString& enter_event = GetEnterEvent(); |
125 for (size_t i = 0; i < entered_ancestors.size(); i++) { | 122 for (size_t i = 0; i < entered_ancestors.size(); i++) { |
126 if (entered_ancestors[i]->HasCapturingEventListeners(enter_event)) { | 123 if (entered_ancestors[i]->HasCapturingEventListeners(enter_event)) { |
127 entered_node_has_capturing_ancestor = true; | 124 entered_node_has_capturing_ancestor = true; |
128 break; | 125 break; |
129 } | 126 } |
130 } | 127 } |
131 | 128 |
132 // Dispatch enter events, in parent-to-child order. | 129 // Dispatch enter events, in parent-to-child order. |
133 for (size_t i = entered_ancestors_common_parent_index; i > 0; i--) | 130 for (size_t i = entered_ancestors_common_parent_index; i > 0; i--) |
134 DispatchEnter(entered_ancestors[i - 1], exited_target, | 131 DispatchEnter(entered_ancestors[i - 1], exited_target, |
135 !entered_node_has_capturing_ancestor); | 132 !entered_node_has_capturing_ancestor); |
136 } | 133 } |
137 | 134 |
138 } // namespace blink | 135 } // namespace blink |
OLD | NEW |