Chromium Code Reviews| Index: third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| index 9f8556979c8d409b9338455f071d73f776cfc2b2..12bea1e551c5859df2148eff59bdf2ce4df9760a 100644 |
| --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| @@ -79,6 +79,42 @@ PlatformMouseEvent mouseEventWithRegion(Node* node, const PlatformMouseEvent& mo |
| return newMouseEvent; |
| } |
| +void buildAncestorChainsAndFindCommonAncestors( |
| + EventTarget* exitedTarget, EventTarget* enteredTarget, |
|
bokan
2016/04/21 21:38:29
Seems like these can't be null? If that's true, ma
Navid Zolghadr
2016/04/21 23:40:14
No. They can be null. The isInDocument checks for
bokan
2016/04/22 00:52:54
Got it, ok, fine as they are (if possible though,
Navid Zolghadr
2016/04/22 17:04:12
This turned out to be harder than I thought. Marki
bokan
2016/04/22 17:30:52
Nah, if it's more trouble lgtm as-is. Our code is
|
| + HeapVector<Member<Node>, 20> &exitedAncestors, |
| + HeapVector<Member<Node>, 20> &enteredAncestors, |
| + size_t& exitedAncestorsCommonParentIndex, |
| + size_t& enteredAncestorsCommonParentIndex) |
|
bokan
2016/04/21 21:38:28
Output parameters should be passed by pointer.
Navid Zolghadr
2016/04/21 23:40:14
You mean like size_t* and HeapVector<Member<Node>
bokan
2016/04/22 00:52:54
Yup, see the bit about output params here: https:/
Navid Zolghadr
2016/04/22 17:04:12
Done.
|
| +{ |
| + // Index 0 element in the ancestors arrays will be the corresponding |
| + // target. So the root of their document will be their last element. |
| + |
|
bokan
2016/04/21 21:38:29
I see you check if exitedTarget == enteredTarget b
Navid Zolghadr
2016/04/21 23:40:14
I don't think that is needed. This function doesn'
bokan
2016/04/22 00:52:54
Whoops, yah, you're right. That's fine.
|
| + if (isInDocument(exitedTarget)) { |
| + Node* exitedNode = exitedTarget->toNode(); |
|
bokan
2016/04/21 21:38:28
Either DCHECK that exitedNode != nullptr (if indee
Navid Zolghadr
2016/04/21 23:40:14
Neither the DCHECK nor the behavior of handling wh
bokan
2016/04/22 00:52:54
Acknowledged.
Navid Zolghadr
2016/04/22 17:04:12
Done.
|
| + exitedNode->updateDistribution(); |
| + for (Node* node = exitedNode; node; node = FlatTreeTraversal::parent(*node)) |
| + exitedAncestors.append(node); |
| + } |
| + |
| + if (isInDocument(enteredTarget)) { |
| + Node* enteredNode = enteredTarget->toNode(); |
| + enteredNode->updateDistribution(); |
|
bokan
2016/04/21 21:38:29
Question: what does updateDistribution do?
Navid Zolghadr
2016/04/21 23:40:14
To be honest with you, I'm not sure myself. From t
bokan
2016/04/22 00:52:54
Hmm, I've never seen it before. But I can see it w
|
| + for (Node* node = enteredNode; node; node = FlatTreeTraversal::parent(*node)) |
| + enteredAncestors.append(node); |
| + } |
| + |
| + exitedAncestorsCommonParentIndex = exitedAncestors.size(); |
| + enteredAncestorsCommonParentIndex = enteredAncestors.size(); |
|
bokan
2016/04/21 21:38:29
One more suggested DCHECK here :), exitedAncestors
Navid Zolghadr
2016/04/21 23:40:14
That's not right. They might be from different doc
bokan
2016/04/22 00:52:54
That's what I'm getting at, you have no way of dis
Navid Zolghadr
2016/04/22 01:46:13
No. That is not the case. Here is an example
if we
bokan
2016/04/22 01:50:47
Bah, I'm not having a good day...you're totally ri
|
| + while (exitedAncestorsCommonParentIndex > 0 |
| + && enteredAncestorsCommonParentIndex > 0) { |
| + if (exitedAncestors[exitedAncestorsCommonParentIndex-1] |
| + != enteredAncestors[enteredAncestorsCommonParentIndex-1]) |
| + break; |
| + exitedAncestorsCommonParentIndex--; |
| + enteredAncestorsCommonParentIndex--; |
| + } |
| +} |
| + |
| } // namespace |
| WebInputEventResult PointerEventManager::dispatchPointerEvent( |
| @@ -180,21 +216,12 @@ void PointerEventManager::sendNodeTransitionEvents( |
| } |
| // Create lists of all exited/entered ancestors, locate the common ancestor |
| - HeapVector<Member<Node>, 32> exitedAncestors; |
| - HeapVector<Member<Node>, 32> enteredAncestors; |
| - if (isInDocument(exitedTarget)) { |
| - Node* exitedNode = exitedTarget->toNode(); |
| - exitedNode->updateDistribution(); |
| - for (Node* node = exitedNode; node; node = FlatTreeTraversal::parent(*node)) |
| - exitedAncestors.append(node); |
| - } |
| - |
| - if (isInDocument(enteredTarget)) { |
| - Node* enteredNode = enteredTarget->toNode(); |
| - enteredNode->updateDistribution(); |
| - for (Node* node = enteredNode; node; node = FlatTreeTraversal::parent(*node)) |
| - enteredAncestors.append(node); |
| - } |
| + // Based on httparchive, in more than 97% cases the depth of DOM is less |
|
bokan
2016/04/21 21:38:29
Doesn't this mean that in 3% of cases we'll incur
Navid Zolghadr
2016/04/21 23:40:14
I don't have a strong answer here.
I had it at 32.
bokan
2016/04/22 00:52:54
Heap allocations can be fairly expensive and unpre
|
| + // than 20. |
| + HeapVector<Member<Node>, 20> exitedAncestors; |
| + HeapVector<Member<Node>, 20> enteredAncestors; |
| + size_t exitedAncestorsCommonParentIndex = 0; |
| + size_t enteredAncestorsCommonParentIndex = 0; |
| // A note on mouseenter and mouseleave: These are non-bubbling events, and they are dispatched if there |
| // is a capturing event handler on an ancestor or a normal event handler on the element itself. This special |
| @@ -210,22 +237,10 @@ void PointerEventManager::sendNodeTransitionEvents( |
| // |
| // TODO(mustaq): Confirm spec conformance, double-check with other browsers. |
| - size_t numExitedAncestors = exitedAncestors.size(); |
| - size_t numEnteredAncestors = enteredAncestors.size(); |
| - |
| - size_t exitedAncestorIndex = numExitedAncestors; |
| - size_t enteredAncestorIndex = numEnteredAncestors; |
| - for (size_t i = 0; i < numExitedAncestors; i++) { |
| - for (size_t j = 0; j < numEnteredAncestors; j++) { |
| - if (exitedAncestors[i] == enteredAncestors[j]) { |
| - exitedAncestorIndex = i; |
| - enteredAncestorIndex = j; |
| - break; |
| - } |
| - } |
| - if (exitedAncestorIndex < exitedAncestors.size()) |
| - break; |
| - } |
| + buildAncestorChainsAndFindCommonAncestors( |
| + exitedTarget, enteredTarget, |
| + exitedAncestors, enteredAncestors, |
| + exitedAncestorsCommonParentIndex, enteredAncestorsCommonParentIndex); |
| bool exitedNodeHasCapturingAncestor = false; |
| for (size_t j = 0; j < exitedAncestors.size(); j++) { |
| @@ -236,7 +251,7 @@ void PointerEventManager::sendNodeTransitionEvents( |
| } |
| // Dispatch pointerleave/mouseleave events, in child-to-parent order. |
| - for (size_t j = 0; j < exitedAncestorIndex; j++) { |
| + for (size_t j = 0; j < exitedAncestorsCommonParentIndex; j++) { |
| if (!sendMouseEvent) { |
| dispatchPointerEvent(exitedAncestors[j].get(), |
| m_pointerEventFactory.createPointerTransitionEvent( |
| @@ -272,7 +287,7 @@ void PointerEventManager::sendNodeTransitionEvents( |
| } |
| // Dispatch pointerenter/mouseenter events, in parent-to-child order. |
| - for (size_t i = enteredAncestorIndex; i > 0; i--) { |
| + for (size_t i = enteredAncestorsCommonParentIndex; i > 0; i--) { |
| if (!sendMouseEvent) { |
| dispatchPointerEvent(enteredAncestors[i-1].get(), |
| m_pointerEventFactory.createPointerTransitionEvent( |