| Index: third_party/WebKit/Source/core/input/MouseEventManager.cpp
|
| diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
|
| index 966780376fb1bc7464f78fdc74413cb579749d3d..00d486c843cb318e8b153b3c310122f4b098cd3a 100644
|
| --- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp
|
| +++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
|
| @@ -30,6 +30,7 @@
|
| #include "core/page/FocusController.h"
|
| #include "core/paint/PaintLayer.h"
|
| #include "core/svg/SVGDocumentExtensions.h"
|
| +#include "platform/Histogram.h"
|
| #include "platform/geometry/FloatQuad.h"
|
|
|
| namespace blink {
|
| @@ -95,6 +96,7 @@ void MouseEventManager::Clear() {
|
| mouse_pressed_ = false;
|
| click_count_ = 0;
|
| click_element_ = nullptr;
|
| + mouse_down_element_ = nullptr;
|
| mouse_down_pos_ = IntPoint();
|
| mouse_down_timestamp_ = TimeTicks();
|
| mouse_down_ = WebMouseEvent();
|
| @@ -112,6 +114,7 @@ DEFINE_TRACE(MouseEventManager) {
|
| visitor->Trace(node_under_mouse_);
|
| visitor->Trace(mouse_press_node_);
|
| visitor->Trace(click_element_);
|
| + visitor->Trace(mouse_down_element_);
|
| SynchronousMutationObserver::Trace(visitor);
|
| }
|
|
|
| @@ -249,9 +252,10 @@ WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded(
|
| #endif
|
|
|
| const bool should_dispatch_click_event =
|
| - click_count_ > 0 && !context_menu_event && click_element_ &&
|
| + click_count_ > 0 && !context_menu_event && mouse_down_element_ &&
|
| mouse_release_target.CanParticipateInFlatTree() &&
|
| - click_element_->CanParticipateInFlatTree() &&
|
| + mouse_down_element_->CanParticipateInFlatTree() &&
|
| + mouse_down_element_->isConnected() &&
|
| !(frame_->GetEventHandler()
|
| .GetSelectionController()
|
| .HasExtendedSelection() &&
|
| @@ -260,27 +264,45 @@ WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded(
|
| return WebInputEventResult::kNotHandled;
|
|
|
| Node* click_target_node = nullptr;
|
| - if (click_element_ == mouse_release_target) {
|
| - click_target_node = click_element_;
|
| - } else if (click_element_->GetDocument() ==
|
| + if (mouse_down_element_ == mouse_release_target) {
|
| + click_target_node = mouse_down_element_;
|
| + } else if (mouse_down_element_->GetDocument() ==
|
| mouse_release_target.GetDocument()) {
|
| // Updates distribution because a 'mouseup' event listener can make the
|
| // tree dirty at dispatchMouseEvent() invocation above.
|
| // Unless distribution is updated, commonAncestor would hit ASSERT.
|
| - click_element_->UpdateDistribution();
|
| + mouse_down_element_->UpdateDistribution();
|
| mouse_release_target.UpdateDistribution();
|
| click_target_node = mouse_release_target.CommonAncestor(
|
| - *click_element_, EventHandlingUtil::ParentForClickEvent);
|
| + *mouse_down_element_, EventHandlingUtil::ParentForClickEvent);
|
| }
|
| if (!click_target_node)
|
| return WebInputEventResult::kNotHandled;
|
| - return DispatchMouseEvent(
|
| - click_target_node,
|
| - !RuntimeEnabledFeatures::auxclickEnabled() ||
|
| - (mev.Event().button == WebPointerProperties::Button::kLeft)
|
| - ? EventTypeNames::click
|
| - : EventTypeNames::auxclick,
|
| - mev.Event(), mev.CanvasRegionId(), nullptr);
|
| +
|
| + DEFINE_STATIC_LOCAL(BooleanHistogram, histogram,
|
| + ("Event.ClickNotFiredDueToDomManipulation"));
|
| +
|
| + if (click_element_ && click_element_->CanParticipateInFlatTree() &&
|
| + click_element_->isConnected()) {
|
| + DCHECK(click_element_ == mouse_down_element_);
|
| + histogram.Count(false);
|
| + } else {
|
| + histogram.Count(true);
|
| + }
|
| +
|
| + if ((click_element_ && click_element_->CanParticipateInFlatTree() &&
|
| + click_element_->isConnected()) ||
|
| + RuntimeEnabledFeatures::clickRetargettingEnabled()) {
|
| + return DispatchMouseEvent(
|
| + click_target_node,
|
| + !RuntimeEnabledFeatures::auxclickEnabled() ||
|
| + (mev.Event().button == WebPointerProperties::Button::kLeft)
|
| + ? EventTypeNames::click
|
| + : EventTypeNames::auxclick,
|
| + mev.Event(), mev.CanvasRegionId(), nullptr);
|
| + }
|
| +
|
| + return WebInputEventResult::kNotHandled;
|
| }
|
|
|
| void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) {
|
| @@ -386,6 +408,9 @@ void MouseEventManager::NodeChildrenWillBeRemoved(ContainerNode& container) {
|
| if (!container.IsShadowIncludingInclusiveAncestorOf(click_element_.Get()))
|
| return;
|
| click_element_ = nullptr;
|
| +
|
| + // TODO(crbug.com/716694): Do not reset mouse_down_element_ for the purpose of
|
| + // gathering data.
|
| }
|
|
|
| void MouseEventManager::NodeWillBeRemoved(Node& node_to_be_removed) {
|
| @@ -394,6 +419,9 @@ void MouseEventManager::NodeWillBeRemoved(Node& node_to_be_removed) {
|
| // We don't dispatch click events if the mousedown node is removed
|
| // before a mouseup event. It is compatible with IE and Firefox.
|
| click_element_ = nullptr;
|
| +
|
| + // TODO(crbug.com/716694): Do not reset mouse_down_element_ for the purpose
|
| + // of gathering data.
|
| }
|
| }
|
|
|
| @@ -999,6 +1027,7 @@ bool MouseEventManager::HandleSvgPanIfNeeded(bool is_release_event) {
|
| void MouseEventManager::InvalidateClick() {
|
| click_count_ = 0;
|
| click_element_ = nullptr;
|
| + mouse_down_element_ = nullptr;
|
| }
|
|
|
| bool MouseEventManager::MousePressed() {
|
| @@ -1028,6 +1057,7 @@ void MouseEventManager::SetMousePressNode(Node* node) {
|
| void MouseEventManager::SetClickElement(Element* element) {
|
| SetContext(element ? element->ownerDocument() : nullptr);
|
| click_element_ = element;
|
| + mouse_down_element_ = element;
|
| }
|
|
|
| void MouseEventManager::SetClickCount(int click_count) {
|
|
|