Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
What happens on a click
// actual differences (in chrome, IE, Firefox, Safari an Edge are all different) are:
// - behavior in disabled 'form' controls
// - phoning to home base (not here, it's defined elsewhere, can dig it up)
// - dealing with clicks dispatching clicks 'recursively'
// this is HTMLElement::click
void HTMLElement::click() {
DispatchSimulatedClick(nullptr, kSendNoEvents,
SimulatedClickCreationScope::kFromScript);
}
// this is the DispatchSimulatedClick method in event_dispatcher.cc the "heart" of the difference
void EventDispatcher::DispatchSimulatedClick(
Node& node,
Event* underlying_event,
SimulatedClickMouseEventOptions mouse_event_options,
SimulatedClickCreationScope creation_scope) {
// This persistent vector doesn't cause leaks, because added Nodes are removed
// before dispatchSimulatedClick() returns. This vector is here just to
// prevent the code from running into an infinite recursion of
// dispatchSimulatedClick().
DEFINE_STATIC_LOCAL(Persistent<HeapHashSet<Member<Node>>>,
nodes_dispatching_simulated_clicks,
(MakeGarbageCollected<HeapHashSet<Member<Node>>>()));
if (IsDisabledFormControl(&node))
return;
if (nodes_dispatching_simulated_clicks->Contains(&node))
return;
nodes_dispatching_simulated_clicks->insert(&node);
if (mouse_event_options == kSendMouseOverUpDownEvents)
EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseover,
node.GetDocument().domWindow(),
underlying_event, creation_scope))
.Dispatch();
if (mouse_event_options != kSendNoEvents) {
EventDispatcher(node, *MouseEvent::Create(event_type_names::kMousedown,
node.GetDocument().domWindow(),
underlying_event, creation_scope))
.Dispatch();
node.SetActive(true);
EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseup,
node.GetDocument().domWindow(),
underlying_event, creation_scope))
.Dispatch();
}
// Some elements (e.g. the color picker) may set active state to true before
// calling this method and expect the state to be reset during the call.
node.SetActive(false);
// always send click
EventDispatcher(node, *MouseEvent::Create(event_type_names::kClick,
node.GetDocument().domWindow(),
underlying_event, creation_scope))
.Dispatch();
nodes_dispatching_simulated_clicks->erase(&node);
}
@benjamingr

This comment has been minimized.

Copy link
Owner Author

commented Apr 16, 2019

And there is a separate path for 'real' clicks as well as clicks through the debugger (Input.dispatchMouseEvent which is essentially what Selenium calls).

This is part of why automation is hard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.